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. Hadoop生态圈-Hive快速入门篇之HQL的基础语法

    Hadoop生态圈-Hive快速入门篇之HQL的基础语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客的重点是介绍Hive中常见的数据类型,DDL数据定义,DML数据操作 ...

  2. windows之tracert命令

    tracert命令是使用从本地到目标网站所在网络服务器的一系列网络节点的访问速度, 网络节点最多支持显示30个.命令格式是tracert加空格加目标网站名称(也可以输入目标网站的IP地址). 先以百度 ...

  3. @Resource,@Autowired,@Inject3种注入方式

    概况 @Resource,@Autowired,@Inject 这3种都是用来注入bean的,它们属于不同的程序中. ANNOTATION PACKAGE SOURCE @Resource javax ...

  4. [转载]HTML5开发入门经典教程和案例合集(含视频教程)

    http://www.iteye.com/topic/1132555 HTML5作为下一代网页语言,对Web开发者而言,是一门必修课.本文档收集了多个HTML5经典技术文档(HTML5入门资料.经典) ...

  5. Eclipse中如何调整字体

    Eclipse 字体有两处,一处是控制台的字体,一处是主窗口.这里分别介绍控制台和主窗口字体的调节方法. Window -> Preferences -> General -> Ap ...

  6. 【leetcode 简单】 第一百四十六题 最长和谐子序列

    和谐数组是指一个数组里元素的最大值和最小值之间的差别正好是1. 现在,给定一个整数数组,你需要在所有可能的子序列中找到最长的和谐子序列的长度. 示例 1: 输入: [1,3,2,2,5,2,3,7] ...

  7. HDU 1427 速算24点 (深搜)

    题目链接 Problem Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用' ...

  8. 如何清理休眠文件(hiberfil.sys)

    如果使用了休眠功能,那么打开系统盘就会有一个很大(5.36G)的hiberfil.sys文件,它是将用户正在运行的程序,保存在这里,再启动系统就很快了.如要清理它(不用休眠功能,或者临时腾出空间),可 ...

  9. 2016.08.02 math(leetcode) 小结

    math(leetcode) 小结 在leetcode中有些知识点(套路) 判断一个数是不是能被某些数整除,可以用 n%x == 0,循环除的话,就将while(n%x == 0)的循环条件设置判断整 ...

  10. Hibernate5笔记6--Hibernate检索优化

    Hibernate检索优化: 检索即查询.为了减轻DB的访问压力,提高检索效率,Hibernate对检索进行了优化. 所谓检索优化,指的是对查询语句的执行时机进行了细致.严格的把控:并不是代码中一出现 ...