【模板】计算几何极角排序扫描线双指针

poj2280:https://vjudge.net/problem/POJ-2280

扫描线双指针,适用性很强

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<iostream>
  4 using namespace std;
  5 typedef long long ll;
  6 const int N = 1000+9;
  7 struct Point{
  8     int x,y;
  9     int col;
 10     Point(){
 11         x = y = 0;
 12     }
 13     Point(int xx,int yy){
 14         x = xx;
 15         y = yy;
 16         col = 0;
 17     }
 18     int cross(const Point& b,const Point& c)const{
 19         return (b.x - x)*(c.y - y) - (c.x - x)*(b.y - y);
 20     }
 21     int dot(const Point& b)const{
 22         return x*b.x + y*b.y;
 23     }
 24     Point operator - (const Point& b)const{
 25         return Point(x - b.x,y - b.y);
 26     }
 27 };
 28 Point p[N<<1],tp[N<<1],p0;
 29 bool cmp(const Point& a,const Point& b){
 30     return p0.cross(a,b) > 0;
 31 }
 32 bool inLine(Point a,Point b){
 33     return (p0.cross(a,b) == 0) && ((a-p0).dot(b-p0) >=0 ) ;
 34 }
 35 bool reLine(Point a,Point b){
 36     return (p0.cross(a,b) == 0) && ( (a - p0).dot(b-p0) <=0);
 37 }
 38 int main(){
 39     int c0,c1;
 40     int n; 
 41     while(scanf("%d",&n) && n){
 42         c0 = c1 = 0;
 43         for(int i = 0;i<n;++i){
 44             scanf("%d %d %d",&p[i].x,&p[i].y,&p[i].col);
 45             if(p[i].col) c1++;
 46             else c0++;
 47         }
 48         int ans = 1;
 49         for(int u = 0; u<n;++u){
 50             p0 = p[u];
 51             int cnt = 0;
 52             for(int i = 0;i<n;++i){
 53                 if(i == u) continue;
 54                 tp[cnt++] = p[i];
 55             }
 56             sort(tp,tp+cnt,cmp);
 57             for(int i = 0;i<cnt;++i) tp[i+cnt] = tp[i];
 58             int t0 = 0,t1 = 0;
 59             int l0 = 0,l1 = 0;
 60             int r0 = 0,r1 = 0;
 61             int j = -1;
 62             if(tp[0].col) ++l1,++t1;
 63             else ++l0,++t0;
 64             for(int i = 0;i<cnt;++i){
 65                 if(j<i){
 66                     t1 = r1 = l1;
 67                     t0 = r0 = l0;
 68                     j = i;
 69                 }
 70                 for(;j - i + 1< n-1 && p0.cross(tp[i],tp[j+1]) >= 0;){
 71                     ++j;
 72                     if(inLine(tp[j],tp[j-1])){
 73                         if(tp[j].col) ++r1,++t1;
 74                         else ++r0,++t0;
 75                     }
 76                     else{
 77                         r1 = r0 = 0;
 78                         if(tp[j].col) ++r1,++t1;
 79                         else ++r0,++t0;
 80                     }
 81                 }
 82                 int tem;
 83                 if(!inLine(tp[i],tp[j])){
 84                     tem = t1  + c0 - t0 + l0;
 85                     if(reLine(tp[i],tp[j])) tem+=r0;
 86                     if(p0.col) ++tem;
 87                 }
 88                 else tem = l0 + l1 +1;
 89                 ans = max(ans,tem);
 90                 if(inLine(tp[i],tp[i+1])){
 91                     if(tp[i+1].col) ++l1;
 92                     else ++l0;
 93                 }
 94                 else{
 95                     t0 -= l0;
 96                     t1 -= l1;
 97                     l1 = l0 = 0;
 98                     if(tp[i+1].col) ++l1;
 99                     else ++l0;
100                 }
101             }
102         }
103         printf("%d\n",ans);
104     }
105     return 0;
106 }
View Code
posted @ 2020-01-12 23:13  小布鞋  阅读(186)  评论(0编辑  收藏  举报