使用叉积进行极角排序HDU1661

解题思路:

扫描线算法。枚举任意一点,其他点依照那一点进行极角排序。扫描获得最大值。

注意:

1、因为 atan2方式的极角排序有精度误差,在这里需要用叉积方式排序。否则就自己慢慢测精度去吧!

2、用叉积方式的极角排序需要将排序的点提前处理到两个象限范围内。注意点属性的状态转换。

3、POJ数据较弱,HDU数据较强。两个OJ都是C++较慢。

  1. #include <set>  
  2. #include <map>  
  3. #include <queue>  
  4. #include <math.h>  
  5. #include <vector>  
  6. #include <string>  
  7. #include <stdio.h>  
  8. #include <string.h>  
  9. #include <stdlib.h>  
  10. #include <iostream>  
  11. #include <algorithm>  
  12.   
  13. #define eps 1e-8  
  14. #define pi acos(-1.0)  
  15. #define inf 107374182  
  16. #define inf64 1152921504606846976  
  17. #define lc l,m,tr<<1  
  18. #define rc m + 1,r,tr<<1|1  
  19. #define iabs(x)  ((x) > 0 ? (x) : -(x))  
  20. #define clear1(A, X, SIZE) memset(A, X, sizeof(A[0]) * (SIZE))  
  21. #define clearall(A, X) memset(A, X, sizeof(A))  
  22. #define memcopy1(A , X, SIZE) memcpy(A , X ,sizeof(X[0])*(SIZE))  
  23. #define memcopyall(A, X) memcpy(A , X ,sizeof(X))  
  24. #define max( x, y )  ( ((x) > (y)) ? (x) : (y) )  
  25. #define min( x, y )  ( ((x) < (y)) ? (x) : (y) )  
  26.   
  27.   
  28. using namespace std;  
  29.   
  30. int n,pointnum,ans,cnt,l,r,sum,num,p;  
  31.   
  32. struct node1  
  33. {  
  34.     int x,y,sta;  
  35. } Point[1005],temp[1005];  
  36.   
  37. int detmul(const node1 a,const node1 b)  
  38. {  
  39.     return a.x * b.y - b.x * a.y;  
  40. }  
  41.   
  42. bool cmp(const node1 a,const node1 b)  
  43. {  
  44.     return detmul(a,b)>0;  
  45. }  
  46.   
  47. int main()  
  48. {  
  49.     while(scanf("%d",&n),n)  
  50.     {  
  51.         for(int i=0; i<n; i++)  
  52.         {  
  53.             scanf("%d%d%d",&Point[i].x,&Point[i].y,&Point[i].sta);  
  54.         }  
  55.         ans=0;  
  56.         for(pointnum=0; pointnum<n; pointnum++)  
  57.         {  
  58.             cnt=0;  
  59.             for(int i=0; i<n; i++)  
  60.             {  
  61.                 if(i==pointnum)continue;  
  62.                 temp[cnt].x=Point[i].x-Point[pointnum].x;  
  63.                 temp[cnt].y=Point[i].y-Point[pointnum].y;  
  64.                 temp[cnt].sta=Point[i].sta;  
  65.                 if(temp[cnt].y<0||(temp[cnt].y==0&&temp[cnt].x<0))  
  66.                 {  
  67.                     temp[cnt].x*=-1;  
  68.                     temp[cnt].y*=-1;  
  69.                     temp[cnt].sta=!temp[cnt].sta;  
  70.                 }  
  71.                 cnt++;  
  72.             }  
  73.             sort(temp,temp+cnt,cmp);  
  74.             l=0;  
  75.             r=0;  
  76.             sum=0;  
  77.             for(int i=0;i<cnt;i++)  
  78.             {  
  79.                 if(temp[i].sta==0)l++;  
  80.             }  
  81.             for(int i=0;i<cnt;i=p)  
  82.             {  
  83.                 num=0;  
  84.                 for(p=i;p<cnt;p++)  
  85.                 {  
  86.                     if(detmul(temp[i],temp[p]))break;  
  87.                     if(temp[p].sta)r++;  
  88.                     else num++;  
  89.                 }  
  90.                 sum=max(sum,l+r+1);  
  91.                 sum=max(sum,cnt-l-r+p-i+1);  
  92.                 l-=num;  
  93.             }  
  94.             ans=max(ans,sum);  
  95.         }  
  96.         printf("%d\n",ans);  
  97.     }  
  98.     return 0;  
  99. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值