uva 11665 Chinese Ink (几何+并查集)
随便给12的找了一道我没做过的几何基础题。这题挺简单的,不过uva上通过率挺低,通过人数也不多。
题意是要求给出的若干多边形组成多少个联通块。做的时候要注意这题是不能用double浮点类型的,然后判多边形交只需要两个条件,存在边规范相交,或者存在一个多边形上的顶点在另一个多边形上或者在多边形内。
代码如下:
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 8 const double EPS = 1e-10; 9 const int N = 44; 10 const int M = 11; 11 inline int sgn(double x) { return (x > EPS) - (x < -EPS);} 12 13 struct Point { 14 int x, y; 15 Point() {} 16 Point(int x, int y) : x(x), y(y) {} 17 Point operator + (Point a) { return Point(x + a.x, y + a.y);} 18 Point operator - (Point a) { return Point(x - a.x, y - a.y);} 19 Point operator * (int p) { return Point(x * p, y * p);} 20 Point operator / (int p) { return Point(x / p, y / p);} 21 } ; 22 23 inline int cross(Point a, Point b) { return a.x * b.y - a.y * b.x;} 24 inline int dot(Point a, Point b) { return a.x * b.x + a.y * b.y;} 25 26 inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == 0 && sgn(dot(a - x, b - x)) <= 0;} 27 bool ptinpoly(Point x, Point *pt, int n) { 28 pt[n] = pt[0]; 29 int wn = 0; 30 for (int i = 0; i < n; i++) { 31 if (onseg(x, pt[i], pt[i + 1])) return true; 32 int dr = sgn(cross(pt[i + 1] - pt[i], x - pt[i])); 33 int k1 = sgn(pt[i + 1].y - x.y); 34 int k2 = sgn(pt[i].y - x.y); 35 if (dr > 0 && k1 > 0 && k2 <= 0) wn++; 36 if (dr < 0 && k2 > 0 && k1 <= 0) wn--; 37 } 38 return wn != 0; 39 } 40 41 struct MFS { 42 int fa[N], cnt; 43 void init() { for (int i = 0; i < N; i++) fa[i] = i; cnt = 0;} 44 int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]);} 45 void merge(int x, int y) { 46 int fx = find(x); 47 int fy = find(y); 48 if (fx == fy) return ; 49 cnt++; 50 fa[fx] = fy; 51 } 52 } mfs; 53 54 Point poly[N][M]; 55 char buf[111]; 56 int sz[N]; 57 58 bool ssint(Point a, Point b, Point c, Point d) { 59 int s1 = sgn(cross(a - c, b - c)); 60 int s2 = sgn(cross(a - d, b - d)); 61 int t1 = sgn(cross(c - a, d - a)); 62 int t2 = sgn(cross(c - b, d - b)); 63 return s1 * s2 < 0 && t1 * t2 < 0; 64 } 65 66 bool polyint(int a, int b) { 67 poly[a][sz[a]] = poly[a][0]; 68 poly[b][sz[b]] = poly[b][0]; 69 for (int i = 0; i < sz[a]; i++) { 70 for (int j = 0; j < sz[b]; j++) { 71 if (ssint(poly[a][i], poly[a][i + 1], poly[b][j], poly[b][j + 1])) return true; 72 } 73 } 74 return false; 75 } 76 77 bool test(int a, int b) { 78 for (int i = 0; i < sz[a]; i++) if (ptinpoly(poly[a][i], poly[b], sz[b])) return true; 79 for (int i = 0; i < sz[b]; i++) if (ptinpoly(poly[b][i], poly[a], sz[a])) return true; 80 if (polyint(a, b)) return true; 81 return false; 82 } 83 84 int main() { 85 //freopen("in", "r", stdin); 86 int n; 87 while (cin >> n && n) { 88 gets(buf); 89 char *p; 90 mfs.init(); 91 for (int i = 0; i < n; i++) { 92 gets(buf); 93 p = strtok(buf, " "); 94 for (sz[i] = 0; p; sz[i]++) { 95 sscanf(p, "%d", &poly[i][sz[i]].x); 96 p = strtok(NULL, " "); 97 sscanf(p, "%d", &poly[i][sz[i]].y); 98 p = strtok(NULL, " "); 99 } 100 //cout << sz[i] << endl; 101 for (int j = 0; j < i; j++) if (test(i, j)) { 102 mfs.merge(i, j); 103 //cout << i << ' ' << j << endl; 104 } 105 } 106 cout << n - mfs.cnt << endl; 107 } 108 return 0; 109 }
——written by Lyon