POJ - 1696 Space Ant
传送门:Space Ant
题意
给出n个点,有一个小人,他每次只能往左边拐,并且不能走以前走过的路,走的路线也不能相交,问他怎么走可以走的路程最大。
题解
可以想到肯定是所有的点都走到路径会最大,然后就很容易想到这不就可以一直凸包了吗!!每次形成凸包的点删掉再继续凸包,然后每次把点的编号加入队列中,直到没有点没被走过。我用的是graham算法的凸包,先找到纵坐标最小的点,第一次按照极角排序是判断和该点连线的极角,后边都是和前一次凸包里的最后一个点的连线形成的极角判断。(想法很简单,实现好麻烦....)
代码
1 #include<stdio.h> 2 #include<algorithm> 3 #include<string.h> 4 #include<queue> 5 #include<math.h> 6 #include<iostream> 7 #define ll long long 8 using namespace std; 9 10 const ll maxn=1e3+10; 11 12 struct node 13 { 14 ll x,y; 15 ll id; 16 }p[maxn],s[maxn],q[maxn]; 17 18 ll xx,yy; 19 20 ll cross(node a,node b,node c) 21 { 22 return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); 23 } 24 25 ll cmp1(node a,node b) 26 { 27 if(a.y==b.y) return a.x<b.x; 28 return a.y<b.y; 29 } 30 31 ll cmp2(node a,node b) 32 { 33 if(atan2(a.y-yy,a.x-xx)-atan2(b.y-yy,b.x-xx)==0) return a.x<b.x; 34 else return atan2(a.y-yy,a.x-xx)<atan2(b.y-yy,b.x-xx); 35 } 36 37 queue<ll>qq; 38 bool vis[maxn]; 39 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 cin.tie(0); 44 cout.tie(0); 45 int t; 46 cin>>t; 47 while(t--){ 48 memset(vis,0,sizeof(vis)); 49 while(!qq.empty()) qq.pop(); 50 ll n; 51 cin>>n; 52 for(ll i=0;i<n;i++){ 53 cin>>q[i].id>>q[i].x>>q[i].y; 54 p[i]=q[i]; 55 } 56 sort(q,q+n,cmp1); 57 ll id; 58 xx=q[0].x,yy=q[0].y,id=q[0].id; 59 qq.push(q[0].id); 60 vis[q[0].id]=1; 61 while(1){ 62 ll l=0; 63 for(ll i=0;i<n;i++) if(!vis[q[i].id]) p[l++]=q[i]; 64 // cout<<l<<endl; 65 if(!l) break; 66 sort(p,p+l,cmp2); 67 if(l==1) {qq.push(p[0].id);break;} 68 else if(l==2) {qq.push(p[0].id),qq.push(p[1].id);break;} 69 else{ 70 s[0].x=xx,s[0].y=yy,s[0].id=id;s[1]=p[0]; 71 ll top=1; 72 for(ll i=1;i<l;i++){ 73 while(top&&cross(s[top-1],s[top],p[i])<=0) top--; //<=可以去掉重边 74 //如果是向右转,这个中间点就不是我们要找的点 75 s[++top]=p[i];//如果是向左转,就加进来 76 } 77 for(ll i=0;i<=top;i++){ 78 if(!vis[s[i].id]) qq.push(s[i].id); 79 vis[s[i].id]=1; 80 } 81 xx=s[top].x,yy=s[top].y,id=s[top].id; 82 } 83 } 84 cout<<qq.size(); 85 while(!qq.empty()) { 86 cout<<' '<<qq.front(); 87 qq.pop(); 88 } 89 cout<<endl; 90 } 91 return 0; 92 }