题意:有个虫子只能向左拐,给定平面上若干点,问这个虫子最多能到达多少个点,并依次输出经过的点。
思路:一开始的思路是做多次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;
}
graham代码会有几组数据挂掉(discuss里有个人提供了很多数据):
#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;
}