巨人与鬼

问题描述:

    

 

 

 代码实现:

 1 #include <iostream>
 2 #include <cmath>   //包含atan2(double,double)函数,求正切值
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 100000;
 6 struct point {
 7     int x, y, flag, num;   //flag 取0,1值,表示鬼和巨人
 8 } p[maxn], temp;
 9 int ans[maxn], n;
10 
11 bool cmp1(point a, point b) 
12 {
13     return a.y !=b.y ? a.y < b.y : a.x < b.x;
14 }
15 
16 bool cmp2(point a, point b) 
17 {
18     return atan2(a.y - temp.y, a.x -temp.x ) < atan2(b.y - temp.y, b.x - temp.x);
19 }
20 
21 void findx(int left, int right) 
22 {
23     if(left > right ) return ;
24     sort(p+left, p+right+1, cmp1);  // 找到左下角的点,sort右不包含
25     temp = p[left];    
26     sort(p+left, p+right+1, cmp2); //从 某一边的弧度开始找。。。弧度排序后,temp=p[left]    
27     int cnt1 = 0, cnt2 = 0, k = right;      
28     while(!(temp.flag != p[k].flag&&cnt1 == cnt2))    //当p[k]和tempflag不同,且cnt1==cnt2时,temp(也就是按角度排序后的p[left])正好和p[k]组一队,
29                                                     //连线一边已经有cnt1对可以继续递归划分,另一边无疑也是整数对可以继续划分
30                                                       
31     {                                                    
32         if(temp.flag == p[k].flag) cnt1++; //  相同的加    巨人    
33         else cnt2++;  //不相同的加 鬼        
34         k--;
35     }
36     ans[temp.num] = p[k].num;
37     ans[p[k].num] = temp.num;
38     findx(left + 1, k - 1);
39     findx(k + 1, right);
40 }
41 
42 int main() 
43 {
44     cin >> n;
45     for(int i = 1; i <= n; ++i) cin >> p[i].x >> p[i].y >> p[i].flag, p[i].num = i;
46     findx(1,n);
47     for(i = 1; i <= n; i++) cout << i << " => " << ans[i] <<endl;
48     return 0;
49 }
//原文参考:https://blog.csdn.net/FireflyNo1/article/details/82869095

运行结果:

 

posted @ 2020-04-28 10:30  kakusan  阅读(202)  评论(0编辑  收藏  举报