1 /* 2 * 题目要求:判断给出的一些折线段是否相交 3 * 解法:枚举每条折线段上的每段线段,判断其是否与其它折线段的线段相交 4 */ 5 6 #include <cstdio> 7 #include <cstdlib> 8 #include <iostream> 9 10 using namespace std; 11 12 const int N = 35; 13 const int M = 105; 14 15 int num[N]; 16 struct point { 17 double x; 18 double y; 19 }p[N][M]; 20 21 double crossProd(point A, point B, point C) { 22 return (B.x-A.x)*(C.y-A.y) - (B.y-A.y)*(C.x-A.x); 23 } 24 25 bool segIntersect(point A, point B, point C, point D) { 26 if (max(A.x, B.x) >= min(C.x, D.x) && 27 max(C.x, D.x) >= min(A.x, B.x) && 28 max(A.y, B.y) >= min(C.y, D.y) && 29 max(C.y, D.y) >= min(A.y, B.y) && 30 crossProd(A, B, C)*crossProd(A, D, B) > 0 && 31 crossProd(C, D, A)*crossProd(C, B, D) > 0) return true; 32 return false; 33 } 34 35 bool solve(int n) { 36 for (int i=0; i<n-1; ++i) {//枚举每条折线段 37 for (int j=1; j<num[i]; ++j) { 38 for (int ii=i+1; ii<n; ++ii) { 39 for (int k=1; k<num[ii]; ++k) { 40 if (segIntersect(p[i][j-1], p[i][j], p[ii][k-1], p[ii][k])) return false;//判断线段相交 41 } 42 } 43 } 44 } 45 return true; 46 } 47 48 int main() { 49 int n; 50 while (scanf("%d", &n) != EOF) { 51 for (int i=0; i<n; ++i) { 52 scanf ("%d", &num[i]); 53 for (int j=0; j<num[i]; ++j) scanf ("%lf%lf", &p[i][j].x, &p[i][j].y); 54 } 55 if (n == 1) printf ("No\n"); 56 else { 57 bool yes = solve(n); 58 if (yes) printf ("No\n"); 59 else printf ("Yes\n"); 60 } 61 } 62 return 0; 63 }