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. Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter)

    Java基础-IO流对象之转换流(InputStreamReader与OutoutStreamWriter) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.转换流概述 我们之前 ...

  2. 科学计算三维可视化---Traits(Event和button属性)

    Event和button属性 是两个专门用于处理事件的change属性 Event属性和其他Trait属性不一样 Button属性是由Event属性继承而来的 Event监听 from traits. ...

  3. appium 使用过程问题踩坑-笔记

    问题1:虚拟设备选用问题 运行脚本抛出异常,创建session对象失败 排查过程:在进入cmd模式下: ①adb devices   --ok ②appium-doctor  --ok ③appium ...

  4. 视差滚动(Parallax Scrolling)的一点小心得

    下面内容来源于我知乎的这个答案:http://www.zhihu.com/question/20990029/answer/21436067 假期有空,整理到博客园这边,并做了一些语境的调整. ——— ...

  5. 高效使用jquery之一:请使用'On'函数

    on函数是在jquery 1.7 加入的 描述: 在选定的元素上绑定一个或多个事件处理函数. 定义:.on( events [, selector ] [, data ], handler(event ...

  6. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

  7. 判断html是否含有图片

    核心代码: $url="http://XXXXX/article/012.html"; $content=file_get_contents($url); //读取文章页面源代码 ...

  8. python的数字IP实现

    第一种方法: import socket, struct >>> def ip2num(ip): ... return struct.unpack("!L", s ...

  9. flask跨域请求三行代码搞定

    flask跨域请求三行代码就可以搞定.但是请注意几点: 第一:只能返回json格式数据,比如list.ndarray等都不可以 第二:返回的对象必须是是字符串.元组.响应实例或WSGI可调用. pyt ...

  10. 【译】第十篇 Replication:故障排除

    本篇文章是SQL Server Replication系列的第十篇,详细内容请参考原文. 复制故障排除是一项艰巨的任务.在任何复制设置中,都涉及到很多移动部件,而可用的工具并不总是很容易识别问题.Th ...