Closed Fences

A closed fence in the plane is a set of non-crossing, connected line segments with N corners (3 < N < 200). The corners or vertices are each distinct and are listed in counter-clockwise order in an array {xi, yi}, i in (1..N).

Every pair of adjacent vertices defines a side of the fence. Thus {xi yi xi+1 yi+1} is a side of the fence for all i in (1..N). For our purposes, N+1 = 1, so that the first and last vertices making the fence closed.

Here is a typical closed fence and a point x,y:

                         * x3,y3
x5,y5 / \
x,y * * / \
/ \ / \
/ * \
x6,y6* x4,y4 \
| \
| \
x1,y1*----------------* x2,y2

Write a program which will do the following:

  • Test an ordered list of vertices {xi,yi}, i in (1..N) to see if the array is a valid fence.
  • Find the set of fence sides that a person (with no height) who is standing in the plane at position (x,y) can "see" when looking at the fence. The location x,y may fall anywhere not on the fence.

A fence side can be seen if there exists a ray that connects (x,y) and any point on the side, and the ray does not intersect any other side of the fence. A side that is parallel to the line of sight is not considered visible. In the figure, above the segments x3,y3-x4,y4; x5,y5-x6,y6; and x6-y6-x1,y1 are visible or partially visible from x,y.

PROGRAM NAME: fence4

INPUT FORMAT

Line 1: N, the number of corners in the fence
Line 2: Two space-separated integers, x and y, that are the location of the observer. Both integers will fit into 16 bits.
Line 3-N+2: A pair of space-separated integers denoting the X,Y location of the corner. The pairs are given in counterclockwise order. Both integers are no larger than 1000 in magnitude.

NOTE: I have added a new test case #12 for this task. Let me know if you think it's wrong. Rob Be sure to include USACO in your mail subject!

SAMPLE INPUT (file fence4.in)

13
5 5
0 0
7 0
5 2
7 5
5 7
3 5
4 9
1 8
2 5
0 9
-2 7
0 3
-3 1

OUTPUT FORMAT

If the sequence is not a valid fence, the output is a single line containing the word "NOFENCE".

Otherwise, the output is a listing of visible fence segments, one per line, shown as four space-separated integers that represent the two corners. Express the points in the segment by showing first the point that is earlier in the input, then the point that is later. Sort the segments for output by examining the last point and showing first those points that are earlier in the input. Use the same rule on the first of the two points in case of ties.

SAMPLE OUTPUT (file fence4.out)

7
0 0 7 0
5 2 7 5
7 5 5 7
5 7 3 5
-2 7 0 3
0 0 -3 1
0 3 -3 1

——————————————————————题解

做的第三道计算几何

首先nofence的判定用两条线段是否相交【此处可能有图】

然后从观察者到一个点偏上一点点,偏下一点点,扫描看相交

然后求一个交点【此处可能有图】

判断交点是否在射线上

然后找一个距离观察者距离最小交点所在篱笆

 /*
LANG: C++
PROG: fence4
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#define siji(i,x,y) for(int i=(x); i <= (y) ; ++i)
#define xiaosiji(i,x,y) for(int i=(x);i < (y); ++i)
#define ivorysi
#define eps 1e-8
#define o(x) ((x)*(x))
using namespace std;
typedef long long ll;
int n;
struct vec{
double x,y;
vec operator - (const vec &rhs)const{
return (vec){x-rhs.x,y-rhs.y};
}
vec operator + (const vec &rhs)const{
return (vec){x+rhs.x,y+rhs.y};
}
vec operator * (double d)const{
return (vec){x*d,y*d};
}
vec operator / (double d)const{
return (vec){x/d,y/d};
}
double norm() const{
return x*x+y*y;
}
}pt[],observer;
struct line {
vec s,t;
}seg[];
bool visible[];
int ans;
double cross(vec a,vec b) {//求叉积
return a.x*b.y-b.x*a.y;
}
vec intersect(line a,line b) {//求交点
double s1=cross(b.s-a.s,b.t-a.s),s2=cross(b.t-a.t,b.s-a.t);
return a.s+(a.t-a.s)*s1/(s1+s2);
}
inline bool dcmp(double a,double b=) {
return fabs( a - b ) <= eps;
} bool iscross(line a,line b) {
if(cross(a.t-a.s,b.s-a.s)*cross(a.t-a.s,b.t-a.s)>= ||
cross(b.t-b.s,a.s-b.s)*cross(b.t-b.s,a.t-b.s)>=) return false;
return true;
}
void init() {
scanf("%d",&n);
scanf("%lf%lf",&observer.x,&observer.y);
siji(i,,n) {
scanf("%lf%lf",&pt[i].x,&pt[i].y);
}
siji(i,,n-) {
seg[i].s=pt[i],seg[i].t=pt[i+];
}
seg[n-].s=pt[],seg[n-].t=pt[n];
seg[n].s=pt[n-],seg[n].t=pt[n];
siji(i,,n) {
siji(j,,n) {
if(i==j) continue;
if(!iscross(seg[i],seg[j])) continue;
puts("NOFENCE");
exit();
}
}
}
void checkline(line l) {
double shortest;
int num=-;
siji(i,,n) {
if(cross(seg[i].s-l.s,l.t-l.s)*cross(seg[i].t-l.s,l.t-l.s)>=) continue;//射线只需要判定一个点
vec temp=intersect(l,seg[i])-l.s;
if(temp.x*(l.t.x-l.s.x) < || temp.y*(l.t.y-l.s.y)<) continue;//假如交点和射线上的点相乘小于0说明是不同方向
if(num==-) {
num=i;shortest=temp.norm();
}
else if(shortest>temp.norm()){
shortest=temp.norm();
num=i;
}
}
if(num!=-) visible[num]=;
}
void solve() {
init();
line l;
l.s=observer;
siji(i,,n) {
double angle=atan2(pt[i].y-l.s.y,pt[i].x-l.s.x);
l.t=l.s+(vec){cos(angle+eps),sin(angle+eps)};//偏上一点点
checkline(l);
l.t=l.s+(vec){cos(angle-eps),sin(angle-eps)};//偏下一点点
checkline(l);
}
siji(i,,n) {
if(visible[i]) ++ans;
}
printf("%d\n",ans);
siji(i,,n) {
if(visible[i]) printf("%d %d %d %d\n",
(int)seg[i].s.x,(int)seg[i].s.y,(int)seg[i].t.x,(int)seg[i].t.y);
}
}
int main(int argc, char const *argv[])
{
#ifdef ivorysi
freopen("fence4.in","r",stdin);
freopen("fence4.out","w",stdout);
#else
freopen("f1.in","r",stdin);
//freopen("f1.out","w",stdout);
#endif
solve();
return ;
}

USACO 6.5 Closed Fences的更多相关文章

  1. USACO 6.4 Electric Fences

    Electric FencesKolstad & Schrijvers Farmer John has decided to construct electric fences. He has ...

  2. USACO6.5-Closed Fences:计算几何

    Closed Fences A closed fence in the plane is a set of non-crossing, connected line segments with N c ...

  3. USACO 完结的一些感想

    其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...

  4. USACO 6.5 章节 世界上本没有龙 屠龙的人多了也便有了

    All Latin Squares 题目大意 n x n矩阵(n=2->7) 第一行1 2 3 4 5 ..N 每行每列,1-N各出现一次,求总方案数 题解 n最大为7 显然打表 写了个先数值后 ...

  5. USACO 3.3 Riding the Fences

    Riding the Fences Farmer John owns a large number of fences that must be repaired annually. He trave ...

  6. USACO Section 3.3: Riding the Fences

    典型的找欧拉路径的题.先贴下USACO上找欧拉路径的法子: Pick a starting node and recurse on that node. At each step: If the no ...

  7. 「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径

    Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编 ...

  8. 【USACO 3.3】Riding The Fences(欧拉路径)

    题意: 给你每个fence连接的两个点的编号,输出编号序列的字典序最小的路径,满足每个fence必须走且最多走一次. 题解: 本题就是输出欧拉路径. 题目保证给出的图是一定存在欧拉路径,因此找到最小的 ...

  9. USACO Section 3.3 骑马修栅栏 Riding the Fences

    题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...

随机推荐

  1. Mongodb 笔记02 创建、更新和删除文档

    创建.更新和删除文档          1. 插入并保存: 1). 单条插入,insert : db.foo.insert({"bar":"baz"}) 2). ...

  2. [转载]教你如何塑造JavaScript牛逼形象

    http://www.html5cn.org/article-6571-1.html 如何写JavaScript才能逼格更高呢?怎样才能组织JavaScript才能让别人一眼看出你不简单呢?是否很期待 ...

  3. Python核心编程——Chapter15

    正则表达式在脚本语言里是最重要的一部分,这部分的题目真的不容怠慢. 开始这部分的题目的解答! 15.1识别下列字符串:bat,bit,but,hat,hit和hut. >>> imp ...

  4. Arcgis10.1 Arcobject连接Oracel数据库

    原来使用Arcgis9.3的版本,现在升级到了10.1遇到不少问题,原来初始化工作空间的代码无法正常运行了,修改后的代码如下: static void Test() { IPropertySet sd ...

  5. kafka入门(1)- 基本概念

    Kafka is a distributed,partitioned,replicated commit logservice Kafka提供了类似于JMS的特性,但是在设计实现上完全不同,并不是JM ...

  6. Python练习-有点儿意思的用户登录

    Alex大神的需求(说实话他需求真特么多,真难满足他): 编写一个用户登陆接口:输入用户名密码,认证成功后显示欢迎信息,输错三次后锁定; # 编辑者:闫龙 #用户登录功能输入3次以上会被锁定:为了方便 ...

  7. E - Sudoku HDU - 5547 (搜索+暴力)

    题目链接:https://cn.vjudge.net/problem/HDU-5547 具体思路:对于每一位上,我们可以从1到4挨着去试, 具体判断这一位可不可以的时候,看当前这一位上的行和列有没有冲 ...

  8. (一)利用 mdb 调试获取 nvlist_t 中 nvpair_t(name/value) 对

    服务器:192.168.2.122 root@2236:~# mdb -k> ::spaADDR                 STATE NAME                       ...

  9. vue中使用localStorage存储信息

    一 什么是localStorage 对浏览器来说,使用 Web Storage 存储键值对比存储 Cookie 方式更直观,而且容量更大,它包含两种:localStorage 和 sessionSto ...

  10. XSS注入常用语句

    <script>alert('hello,gaga!');</script> //经典语句,哈哈! >"'><img src="javas ...