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 }
时间: 2024-11-23 16:44:22