USACO 6.5 Closed Fences
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的更多相关文章
- USACO 6.4 Electric Fences
Electric FencesKolstad & Schrijvers Farmer John has decided to construct electric fences. He has ...
- USACO6.5-Closed Fences:计算几何
Closed Fences A closed fence in the plane is a set of non-crossing, connected line segments with N c ...
- USACO 完结的一些感想
其实日期没有那么近啦……只是我偶尔还点进去造成的,导致我没有每一章刷完的纪念日了 但是全刷完是今天啦 讲真,题很锻炼思维能力,USACO保持着一贯猎奇的题目描述,以及尽量不用高级算法就完成的题解……例 ...
- USACO 6.5 章节 世界上本没有龙 屠龙的人多了也便有了
All Latin Squares 题目大意 n x n矩阵(n=2->7) 第一行1 2 3 4 5 ..N 每行每列,1-N各出现一次,求总方案数 题解 n最大为7 显然打表 写了个先数值后 ...
- USACO 3.3 Riding the Fences
Riding the Fences Farmer John owns a large number of fences that must be repaired annually. He trave ...
- USACO Section 3.3: Riding the Fences
典型的找欧拉路径的题.先贴下USACO上找欧拉路径的法子: Pick a starting node and recurse on that node. At each step: If the no ...
- 「USACO」「LuoguP2731」 骑马修栅栏 Riding the Fences(欧拉路径
Description Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编 ...
- 【USACO 3.3】Riding The Fences(欧拉路径)
题意: 给你每个fence连接的两个点的编号,输出编号序列的字典序最小的路径,满足每个fence必须走且最多走一次. 题解: 本题就是输出欧拉路径. 题目保证给出的图是一定存在欧拉路径,因此找到最小的 ...
- USACO Section 3.3 骑马修栅栏 Riding the Fences
题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个 ...
随机推荐
- Matlab周期图法使用FFT实现
参考文章:http://www.cnblogs.com/adgk07/p/9314892.html 首先根据他这个代码和我之前手上已经拥有的那个代码,编写了一个适合自己的代码. 首先模仿他的代码,测试 ...
- 如何在Mongodb中实现数据超时自动删除功能?
在工作过程中,我们难免会遇到这样的问题,我们想保存一些数据,但是我们对这些数据的要求并不高,有时候往往只是想要某个时间范围内的数据,比如我们如果永远只关心从当前时间往前推半年内的数据特性,那么我们就不 ...
- JVM加载一个类的过程
类的加载过程 Java源代码被编译成class字节码,JVM把描述类数据的字节码.Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型,这就是虚拟机 ...
- 关于NaN
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 深入分析tcp close与shutdown
关闭socket-close 我们知道,tcp是一种支持全双工(full-duplex)通信的的协议,也就是说建立连接的两端可以在同一个时刻发送.接受数据.在需要关闭套接字的时候,我们一般调用: in ...
- [译]Quartz.NET 框架 教程(中文版)2.2.x 之第五课 SimpleTrigger
第五课 SimpleTrigger 如果你需要在一个指定时间段内执行一次作业任务或是在指定的时间间隔内多次执行作业任务,SimpleTrigger应该能满足你的调度需求.例如,你希望触发器在2015年 ...
- 【BZOJ】2655: calc 动态规划+拉格朗日插值
[题意]一个序列$a_1,...,a_n$合法当且仅当它们都是[1,A]中的数字且互不相同,一个序列的价值定义为数字的乘积,求所有序列的价值和.n<=500,A<=10^9,n+1< ...
- BZOJ1822 Frozen Nova 冷冻波
1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB Description WJJ喜欢“魔兽争霸”这个游戏. ...
- Python练习-猜年龄的LowB游戏
Alex大神今天让我做一个猜年龄的游戏: 第一个游戏是你只能猜三次:真的很LowB啊~ # 编辑者:闫龙 #猜年龄游戏,3次后程序自动退出! ages = 29; #for循环3次 for i in ...
- 用C代码简要模拟实现一下RPC(远程过程调用)并谈谈它在代码调测中的重要应用【转】
转自:http://blog.csdn.net/stpeace/article/details/44947925 版权声明:本文为博主原创文章,转载时请务必注明本文地址, 禁止用于任何商业用途, 否则 ...