24h購物| | PChome| 登入
2013-02-21 22:55:33| 人氣613| 回應0 | 上一篇 | 下一篇

[UVA][凸包關係、射線法、線段交] 10256 - The Great Divide

推薦 1 收藏 0 轉貼0 訂閱站台

Problem K

The Great Divide

Input: standard input

Output: standard output

Time Limit: 8 seconds

Memory Limit: 32 MB

 

Somewhere in Gaul, there is a little village very like the village where Asterix and Obelix live. Not very long ago they had only one chief Altruistix and peace reigned in the village. But now those happy days are just dreams. The villagers are now divided. Some of the villagers have elected Majestix as their chief and the others have elected Cleverdix.

 

                                                                          

Majestix                                              Cleverdix

 

The two chiefs have decided to divide the village into two parts by digging a straight ditch through the middle of the village so that the houses of the supporters of Majestix lie on one part and those of the followers of Cleverdix lie on the other. So, they have invited Getafix, the venerable druid of Asterix’s village, to figure out whether such a dividing line exists or not.

Getafix

 

Since Getafix knows that you are so good in programming, he seeks your help.

 

 

Input

 The input may contain multiple test cases.

 

The first line of each test case contains two integers M and C (1 £ M, C £ 500), indicating the number of houses of the supporters of Majestix and Cleverdix respectively.

 

Each of the next M lines contains two integers x and y (-1000 £ x, y £ 1000) giving the co-ordinates of the house of a supporter of Majestix. For convenience each house is considered as a single point on the plane.

 

Each of the next C lines contains two integers x and y (-1000 £ x, y £ 1000) giving the co-ordinates of the house of a supporter of Cleverdix.

 

The input will terminate with two zeros for M and C.

 

Output

For each test case in the input output a line containing either “Yes” or “No” depending on whether there exists a straight line that divides the two set of houses. The dividing line can NOT contain points of both sides.

 

Sample Input

4 3
100 600
200 400
600 500
300 700
400 100
600 200
500 300

4 3
100 600
400 100
600 200
500 300
200 400
600 500
300 700

0 0

 

Sample Output

Yes
No


(World Final Warm-up Contest, Problem Setter: Rezaul Alam Chowdhury)


已經在射線法判斷是否在多邊形內部時,就已經有判斷是否在線段上了,
因此在線段交的部分,就不特別判斷。

1. 先分別做出凸包

2. 檢查是否另一個凸包在另一個凸包內

3. 檢查凸包的邊是否有相交

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
using namespace std;
struct Pt {
    double x, y;
};
#define eps 1e-8
double cross(Pt o, Pt a, Pt b) {
    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}
int inPolygon(Pt p[], Pt q, int n) {
    if(n == 1)  return 0; // false
    if(n == 2) { // on segment
        if(p[0].x > q.x != p[1].x > q.x &&
           p[0].y > q.y != p[1].y > q.y &&
           fabs(cross(p[0], p[1], q)) < eps)
           return 1;
        return 0;
    }
    int i, j, k = 0;
    for(i = 0, j = n-1; i < n; j = i++) {
        if(p[i].y > q.y != p[j].y > q.y &&
           q.x < (p[j].x-p[i].x)*(q.y-p[i].y)/(p[j].y-p[i].y)+p[i].x)
           k++;
    }
    return k&1;
}
bool cmp(Pt a, Pt b) {
    if(a.x != b.x)
        return a.x < b.x;
    return a.y < b.y;
}
int monotone(Pt p[], int n, Pt ch[]) {
    sort(p, p+n, cmp);
    int i, m = 0, t;
    for(i = 0; i < n; i++) {
        while(m >= 2 && cross(ch[m-2], ch[m-1], p[i]) <= 0)
            m--;
        ch[m++] = p[i];
    }
    for(i = n-1, t = m+1; i >= 0; i--) {
        while(m >= t && cross(ch[m-2], ch[m-1], p[i]) <= 0)
            m--;
        ch[m++] = p[i];
    }
    return m-1;
}
int intersection(Pt as, Pt at, Pt bs, Pt bt) {
    if(cross(as, at, bs)*cross(as, at, bt) < 0 &&
       cross(at, as, bs)*cross(at, as, bt) < 0 &&
       cross(bs, bt, as)*cross(bs, bt, at) < 0 &&
       cross(bt, bs, as)*cross(bt, bs, at) < 0)
        return 1;
    return 0;
}
int M, C, i, j, k, l;
Pt Mp[505], Cp[505], Mch[1005], Cch[1005];
void sol() {
    int Mn = monotone(Mp, M, Mch);
    int Cn = monotone(Cp, C, Cch);
    for(i = 0; i < Cn; i++) {
        if(inPolygon(Mch, Cch[i], Mn)) {
            puts("No");
            return;
        }
    }
    for(i = 0; i < Mn; i++) {
        if(inPolygon(Cch, Mch[i], Cn)) {
            puts("No");
            return;
        }
    }
    for(i = 0, j = Mn-1; i < Mn; j = i++) {
        for(k = 0, l = Cn-1; k < Cn; l = k++) {
            if(intersection(Mch[i], Mch[j], Cch[k], Cch[l])) {
                puts("No");
                return;
            }
        }
    }
    puts("Yes");
}
int main() {
    while(scanf("%d %d", &M, &C) == 2 && M) {
        for(i = 0; i < M; i++)
            scanf("%lf %lf", &Mp[i].x, &Mp[i].y);
        for(i = 0; i < C; i++)
            scanf("%lf %lf", &Cp[i].x, &Cp[i].y);
        sol();
    }
    return 0;
}

台長: Morris
人氣(613) | 回應(0)| 推薦 (1)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: UVA |
此分類下一篇:[UVA][strcasecmp] 11056 - Formula 1
此分類上一篇:[UVA][射線法] 634 - Polygon

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文