poj 3304 Segments (计算几何水题)
链接:http://poj.org/problem?id=3304
题意:找出一条直线,使得给出的所有线段在这个直线上的投影有交集。
思路:找出一条直线,使得其与所给的线段有交点。枚举每一个线段的端点,假设直线经过某两点,判断直线是否与其它线段相交。枚举这些点的位置即可。主意其中的输出大小写,我wa了一个晚上就是输出的大小写写错了,无语(小小吐槽一番)!
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 const double eps = 1e-8; 8 const int N = 210; 9 inline int sig(double x) { return (x>eps)-(x<-eps);} 10 11 struct P{ 12 double x, y; 13 inline void in(){ scanf("%lf%lf", &x, &y); } 14 inline bool operator == (const P a){ //同一个点 15 if(sig(x-a.x) == 0 && sig(y-a.y) == 0) return true; 16 return false; 17 } 18 inline double cross(P a, P b) const { //叉积 19 return (x-b.x)*(a.y-b.y) - (a.x-b.x)*(y-b.y); 20 } 21 } p[N]; 22 23 int t, n; 24 25 int main() 26 { 27 int i, j, k; 28 //freopen("in.txt", "r", stdin); 29 scanf("%d", &t); 30 while(t--) 31 { 32 scanf("%d", &n); 33 n += n; 34 for(i = 0; i < n; i++) p[i].in(); 35 bool fg = 0; 36 for(i = 0; i < n && !fg; i++) 37 for( j = 0; j < n; j++) 38 { 39 if(p[i] == p[j]) continue; 40 for(k = 0; k < n; k += 2) 41 if(p[k].cross(p[i], p[j]) * p[k+1].cross(p[i], p[j]) > eps) // 不相交,不符合 42 break; 43 if(k >= n) fg = 1; 44 } 45 puts((fg) ? "Yes!" : "No!"); 46 } 47 return 0; 48 }