UVa 1411 Ants(分治)

https://vjudge.net/problem/UVA-1411

题意:n只蚂蚁和n颗苹果树,一一配对并且不能交叉。

思路:这就是巨人与鬼的问题。用分治法就行了。

 1 #include<iostream>  
 2 #include<algorithm>
 3 #include<set>
 4 using namespace std;
 5 
 6 int n;
 7 const int maxn = 205;
 8 
 9 int vis[maxn];
10 
11 struct node
12 {
13     int x, y;
14     int id;
15     int flag;
16 }ans[maxn];
17 
18 
19 node s;
20 
21 bool cmp1(node a, node b)   //按y坐标从小到大排序
22 {
23     return a.y < b.y || (a.y == b.y && a.x < b.x);
24 }
25 
26 bool cmp2(node a, node b)  //极角从小到大排序
27 {
28     return ((a.x - s.x)*(b.y - s.y) - (a.y - s.y)*(b.x - s.x))<0;
29 }
30 
31 void solve(int l,int r)
32 {
33     if (l>r)  return;
34     sort(ans + l, ans + r + 1, cmp1);
35     s = ans[l];
36     sort(ans + l + 1, ans + r + 1, cmp2);
37     int cnt1 = 0, cnt2 = 0;
38     int k = r;
39     while (!(s.flag != ans[k].flag && cnt1 == cnt2))
40     {
41         if (ans[k].flag == s.flag)  cnt1++;
42         else cnt2++;
43         k--;
44     }
45     if (!s.flag)  vis[s.id] = ans[k].id;
46     else  vis[ans[k].id] = s.id;
47     solve(l + 1, k - 1);
48     solve(k + 1, r);
49 }
50 
51 int main()
52 {
53     //freopen("D:\\txt.txt", "r", stdin);
54     while (cin >> n && n)
55     {
56         for (int i = 1; i <= n; i++)
57         {
58             cin >> ans[i].x >> ans[i].y;
59             ans[i].id = i;   //蚂蚁编号
60             ans[i].flag = 0;  //0代表蚂蚁
61         }
62         for (int i = n + 1; i <= 2 * n; i++)
63         {
64             cin >> ans[i].x >> ans[i].y;
65             ans[i].id = i - n;  //苹果树编号
66             ans[i].flag = 1;     //1代表苹果树
67         }
68         solve(1,2*n);
69         for (int i = 1; i <= n; i++)
70             cout << vis[i] << endl;
71     }
72     return 0;
73 }

 

posted @ 2017-01-26 20:10  Kayden_Cheung  阅读(480)  评论(0编辑  收藏  举报
//目录