算法学习 寻找最大凸多边形
#include <stdio.h> #include <stdlib.h> #include <string.h> int find(int va,int num,float *lcos); int check(float cos1,float cos2); float ad_cos(int x,int y); typedef struct POINT{ int x; int y; int flag; }Point; Point a[65535]; int main(void) { int i,num,start,j,ret; int result[65535]={0}; scanf("%d",&num); start = 0; for(i=0;i<num;i++){ getchar();//ignore ';' scanf("%d,%d",&(a[i].x),&(a[i].y)); a[i].flag=0; if(a[i].y>a[start].y||((a[i].y==a[start].y)&&(a[i].x<a[start].x)))//use the top point as the start point start = i; } result[0]=start; i = 1; ret = start; float lcos = -2;//first last angel not exist so use -2 while(1){ ret=find(ret,num,&lcos); if(ret==start) break; result[i++]=ret; } for(j=0;j<i-2;j++) printf("%d,%d;",a[result[j]].x,a[result[j]].y); printf("%d,%d",a[result[i-1]].x,a[result[i-1]].y); return 0; } int find(int va,int num,float *lcos) { int i,x,y,min,xmin; float cosi,mcos;//lcos record last round cos,mcos record this round min cos min = -1; for(i=0;i<num;i++){ if(a[i].flag==1||i==va) continue; x=a[i].x-a[va].x; y=a[i].y-a[va].y; cosi = ad_cos(x,y); if(x==y&&x==0) return -1;//error input value if(min==-1){//get first effective point if(check(cosi,*lcos)!=1)//new angle must be bigger than the last round. continue; xmin = x; min = i; mcos = cosi; } else{ if(check(cosi,mcos)==0&&check(cosi,*lcos)==1){//find the min angle point also,the min angle is bigger than the last round. xmin = x; min = i; mcos = cosi; } } } for(i=0;i<num;i++){//remove point on line of this round if(a[i].flag==1||i==va) continue; x=a[i].x-a[va].x; y=a[i].y-a[va].y; cosi = ad_cos(x,y); if(check(cosi,mcos)==3) { if(abs(x)>abs(xmin)){ a[min].flag = 1; min = i; } else a[i].flag=1; } } a[min].flag = 1; *lcos = mcos; return min; } //this func adjust the cos,and finally,the bigger cos,the bigger angle.: float ad_cos(int x,int y){ float cos1 = 0; cos1 = x*x*1.0/(x*x+y*y); if(x<0) cos1 = cos1*(-1); if(y<=0) cos1 = (-1)*cos1; else cos1 = cos1+2; return cos1; } int check(float cos1,float cos2) { if(cos1<cos2) return 0; else if(cos1>cos2) return 1; else return 3; }