题意:有个虫子只能向左拐,给定平面上若干点,问这个虫子最多能到达多少个点,并依次输出经过的点。
思路:一开始的思路是做多次graham,每次最后一个点不取回出发点,但是一直会wa。
所以只能用极角排序,时间复杂度O(n*n*lgn)。
#include <stdio.h> #include <string.h> #include <math.h> #define N 55 struct node{ int id,x,y; }p[N],res[N]; int n,re,T,top; double dis(struct node a,struct node b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int multi(struct node a,struct node b,struct node c){ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } int cmp(const struct node *a,const struct node *b){ int temp = multi(res[top],*a,*b); if(temp != 0)//如果极角分出大小;注意排序的顺序 return -temp; return dis(res[top],*a)-dis(res[top],*b);//否则先找离其实点近的 } int main(){ freopen("a.txt","r",stdin); scanf("%d",&T); while(T--){ int i,miny; top = -1; scanf("%d",&n); for(i = miny = 0;i<n;i++){ scanf("%d %d %d",&p[i].id,&p[i].x,&p[i].y); if(p[i].y < p[miny].y) miny = i; } if(miny){//寻找y坐标最小的点当作初始点 struct node temp = p[0]; p[0] = p[miny]; p[miny] = temp; } printf("%d ",n); res[++top] = p[0]; for(i = 1;i<n-1;i++){//依次对剩下的点进行极角排序 qsort(p+i,n-i,sizeof(struct node),cmp); res[++top] = p[i];//站在初始点来看,选出的是最右侧的点 } res[++top] = p[n-1]; for(i = 0;i<=top;i++) printf("%d ",res[i].id); putchar('\n'); } return 0; }
#include <stdio.h> #include <string.h> #define N 55 struct node{ int id,x,y; }p[N],s[N]; int n,re,T; int cmp(const struct node *a,const struct node *b){ if((*a).y == (*b).y) return (*a).x - (*b).x; return (*a).y - (*b).y; } int multi(struct node a,struct node b,struct node c){ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x); } int graham(){ int i,j,k,m; for(i = m = 0;i<n;i++){ while(m>1 && multi(s[m-2],s[m-1],p[i])<=0) m--; s[m++] = p[i]; } k = m; if(n>m) for(i = n-2;i>0;i--){ while(m>k && multi(s[m-2],s[m-1],p[i])<=0) m--; s[m++] = p[i]; } for(i = 0;i<m;i++) printf("%d ",s[i].id); for(i = k = 0;i<n;i++){ for(j = 0;j<m;j++) if(p[i].x==s[j].x && p[i].y==s[j].y) break; if(j == m) p[k++] = p[i]; } n = k; return m; } int main(){ freopen("a.txt","r",stdin); scanf("%d",&T); while(T--){ int i,k; scanf("%d",&n); for(i = 0;i<n;i++) scanf("%d %d %d",&p[i].id,&p[i].x,&p[i].y); printf("%d ",re = n); qsort(p,n,sizeof(struct node),cmp); while(1){ graham(); if(n <= 1){ if(n == 1) printf("%d",p[0].id); break; } } putchar('\n'); } return 0; }