首页 > 代码库 > UVa 1411 Ants(分治)

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 node12 {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 }

 

UVa 1411 Ants(分治)