uva 361 - Cops and Robbers(凸包)

题目中给出了n个cops和m个robbers和q个居民,如果一个居民在某三个cops围成的三角形中就是安全的,否则,如果在某三个robbers围成的三角形中,就是不安全的,不然就是neither。

思路:这个可以转换成凸包来做。判断某个居民是不是在某个凸包内部就行了。
:下面是凸包的求法之一

int getConvexHull (Point* p, int n, Point* ch) {
    sort(p, p + n);
    // for (int i = 0;i < n;++i)
    // p[i].write(), puts("");
    // puts("");
    int m = 0;
    for (int i = 0; i < n; i++) {
        /* 可共线 */
        //while (m > 1 && dcmp(getCross(ch[m-1]-ch[m-2], p[i]-ch[m-1])) < 0) m--;
        while (m > 1 && dcmp(getCross(ch[m-1]-ch[m-2], p[i]-ch[m-1])) <= 0) 
        {
            // ch[m-1].write(), puts("*******");
            m--;
        }
        ch[m++] = p[i];
    }
    int k = m;
    for (int i = n-2; i >= 0; i--) {
        /* 可共线 */
        //while (m > k && dcmp(getCross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) < 0) m--;
        /*不可共线*/
        while (m > k && dcmp(getCross(ch[m-1]-ch[m-2], p[i]-ch[m-1])) <= 0) {
            // ch[m-1].write(),puts("$$$$$$$$$$");
            m--;
        }
        ch[m++] = p[i];
    }
    if (n > 1) m--;
    // for (int i = 0;i < m;++i)
    // ch[i].write(),puts("^^^^^^^^");
    // puts("");
    return m;
}
点在凸多边形内的判断
int onPolygonal (Point a, Point* p, int n) {
    for (int i = 0; i < n; i++) if (a == p[i]) return 0;
    if (n >= 2) {
        for (int i = 0; i < n; i++) {
            int v = (i + 1) % n;
            if (onSegment(a, p[i], p[v])) return 0;
        }
    }
    if (n <= 2) return 1;

    int sig = dcmp((a - p[0]) * (p[1] - p[0]));
    for (int i = 0; i < n; i++) {
        int v = (i + 1) % n;
        int tsig = dcmp((a - p[i]) * (p[v] - p[i]));
        if (tsig != sig)
            return 1;//在凸多边形外
    }
    return -1;
}

你可能感兴趣的:(凸包简单应用)