C - Segments
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d
& %I64u
Submit Status Practice POJ
3304
Appoint description:
System Crawler (2016-05-07)
Description
Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.
Input
Input begins with a number T showing the number of test cases and then, T test cases follow. Each test case begins with a line containing a positive integer n ≤ 100 showing the number of segments. After that, n lines containing
four real numbers x1y1x2y2 follow, in which (x1, y1) and (x2, y2) are the coordinates of the two
endpoints for one of the segments.
Output
For each test case, your program must output "Yes!", if a line with desired property exists and must output "No!" otherwise. You must assume that two floating point numbers a and b are equal if |a - b| < 10-8.
Sample Input
3 2 1.0 2.0 3.0 4.0 4.0 5.0 6.0 7.0 3 0.0 0.0 0.0 1.0 0.0 1.0 0.0 2.0 1.0 1.0 2.0 1.0 3 0.0 0.0 0.0 1.0 0.0 2.0 0.0 3.0 1.0 1.0 2.0 1.0
Sample Output
Yes! Yes! No! 题意 给你n个线段问是否存在一条直线使得这些线段在这条直线上的投影相交于一点 利用投影的特性就可以知道过这点做垂线必定能与所有的线段相交 那么就转化成了是否存在一条直线和所有线段都相交 如何寻找这条直线呢? 一条直线和线段相交有规范相交和非规范相交 规范相交是指线段的两个端点在直线的两侧 非规范相交是指线段的两个段点至少有一个在直线上 那么对于这道题我们可以把垂线旋转到一定角度一定会出现2条线段与之非规范相交 即过二个线段的端点,那么我们只要枚举任意两个端点就行了 ACcode:#include <cstdio> #include <cmath> #define maxn 200 #define eps 1e-8 int n; int sgn(double x){ if(fabs(x)<eps)return 0; if(x<0)return -1; return 1; } struct Point{ double x,y; Point (){} Point(double _x,double _y){ x=_x; y=_y; } Point operator - (const Point &b)const{ return Point( x-b.x,y-b.y); } double operator ^(const Point &b)const{ return x*b.y-y*b.x; } double operator *(const Point &b)const{ return x*b.x+y*b.y; } }; struct Line{ Point s,e; Line(){} Line(Point _s,Point _e){ s=_s; e=_e; } int linecrossing(Line v){ int d1=sgn((e-s)^(v.s-s)); int d2=sgn((e-s)^(v.e-s)); if((d1^d2)==-2)return 2; return (d1==0||d2==0); } }my[maxn]; double dist(Point a,Point b){ return sqrt( (b - a)*(b - a) ); } bool ju(Line tmp){ if(sgn(dist(tmp.s,tmp.e))==0)return false; for(int i=1;i<=n;++i) if(tmp.linecrossing(my[i])==0) return false; return true; } int main(){ int loop; scanf("%d",&loop); while(loop--){ double x1,x2,y1,y2; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2); my[i]=Line(Point(x1,y1),Point(x2,y2)); } bool flag=true; for(int i=1;flag&&i<=n;++i) for(int j=1;flag&&j<=n;++j) if(ju(Line(my[i].s,my[i].e))||ju(Line(my[i].s,my[j].e))||ju(Line(my[j].s,my[i].s))||ju(Line(my[i].e,my[j].e))) flag=false; printf("%s!\n",!flag?"Yes":"No"); } return 0; }