• uva 11665 Chinese Ink (几何+并查集)


    UVA 11665

      随便给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 }
    View Code

    ——written by Lyon

  • 相关阅读:
    linux系统中SSH免密设置报错
    SSH config语法关键字
    共筑新零售 | 奇点云与阿里云在泛零售数据中台领域达成合作!
    20年零售数字化老兵的“中台战事”
    JAVA中的 <T extends Comparable<? super T>> 如何理解
    JAVA中的比较:comparable、compareTo
    JAVA中PrintWriter的用法
    JAVA中Map类对象如何实现遍历
    JAVA实现通过中序遍历和后序遍历序列建树,并求树的高度,用层次遍历做验证
    密码学相关知识
  • 原文地址:https://www.cnblogs.com/LyonLys/p/uva_11665_Lyon.html
Copyright © 2020-2023  润新知