UVa 1411 Ants(分治)

Posted 谦谦君子,陌上其华

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于UVa 1411 Ants(分治)的主要内容,如果未能解决你的问题,请参考以下文章

UVA1411 Ants

uva 1411 Ants蚂蚁们

题解Luogu UVA1411 Ants

Ants UVA - 1411(竟然让我换了个板子)

UVa 10881Piotr's Ants

cogs 1456. [UVa 10881,Piotr's Ants]蚂蚁