3288655_ac_219ms_1340k.cc

来自「做的POJ的一些题目」· CC 代码 · 共 144 行

CC
144
字号
#include<iostream>
#include<math.h>
#include<stdio.h>
using namespace std;
typedef struct 
{
	float x,y;
	char out[20],out1[20];
}pointt;
float mul(pointt p1,pointt p2,pointt p0)
{
   return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
int partition(pointt a[10000],int p,int r) 
{ 
   int i=p,j=r+1,k; 
   double ang,dis; 
   pointt R,S; 
   k=(p+r)/2;//防止快排退化
   R=a[p]; 
   a[p]=a[k];
   a[k]=R; 
   R=a[p]; 
   dis=sqrt((R.x-a[0].x)*(R.x-a[0].x)+(R.y-a[0].y)*(R.y-a[0].y));
   while(true) 
   { 
      while(true) //找到第一个极角大于0的或极角等于0但距起点比它远的点 
      { 
         ++i; 
         if(i>r) 
         { 
                 i=r; 
                 break; 
         } 
         ang=mul(R,a[i],a[0]); 
         if(ang>0)   break; 
         else if(ang==0) 
         {
              if(sqrt((a[i].x-a[0].x)*(a[i].x-a[0].x)+(a[i].y-a[0].y)*(a[i].y-a[0].y))>dis)
              break; 
         } 
      } 
      while(true) 
      { 
         --j; 
         if(j<p)  
         {
                  j=p; 
                  break;
         } 
         ang=mul(R,a[j],a[0]); 
         if(ang<0) break; 
         else if(ang==0)
         { 
              if(sqrt((a[j].x-a[0].x)*(a[j].x-a[0].x)+(a[j].y-a[0].y)*(a[j].y-a[0].y))<dis) break; 
         } 
      } 
      if(i>=j)break; 
      S=a[i]; 
      a[i]=a[j]; 
      a[j]=S; 
   } 
   a[p]=a[j];
   a[j]=R; 
   return j; 
} 
void anglesort(pointt a[10000],int p,int r) 
{ 
   if(p<r) 
   { 
      int q=partition(a,p,r); 
      anglesort(a,p,q-1); 
      anglesort(a,q+1,r); 
   } 
}
void Graham_scan(pointt point[10000],int n)
{
    pointt ch[10000];
	int i,j,k=0,top=2;
	pointt tmp;
	for(i=1;i<n;i++)
	  if((point[i].y<point[k].y)||((point[i].y==point[k].y)&&(point[i].x<point[k].x)))
	        k=i;
	tmp=point[0];
	point[0]=point[k];
	point[k]=tmp;
    anglesort(point,1,n-1);
	ch[0]=point[0];
	ch[1]=point[1];
	ch[2]=point[2];	
	for (i=3;i<n;i++)
	{
			while(mul(point[i],ch[top],ch[top-1])>=0) 
                top--;
			ch[++top]=point[i];
    }
    for(i=0;i<=top;i++)
   printf("%c%s%c%s%c ",'(',ch[i].out,',',ch[i].out1,')');
   printf("%c%s%c%s%c \n",'(',ch[0].out,',',ch[0].out1,')');
}
int main()
{
   int i,k=0;
   pointt point[10000];
   char c;
   while((c=getchar())!=EOF)
   {
     i=0;
     while(c!='\n')
     {
           if(c=='(')
           {   
              c=getchar();
              while(c!=',')
              {
                point[i].out[k++]=c;
                c=getchar();
              }
              point[i].out[k]='\0';
              k=0;
              point[i].x=atof(point[i].out);
           }
           if(c==',')
           {
              c=getchar();
              while(c!=')')
              {
                point[i].out1[k++]=c;
                 c=getchar();             
              }
              point[i].out1[k]='\0';
              point[i].y=atof(point[i].out1);
              k=0;
              i++;
           }
           c=getchar();            
     }
     Graham_scan(point,i);
   }
   system("pause");
   return 0;    
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?