http://acm.nyist.net/JudgeOnline/problem.php?pid=78
原来Graham都是模板直接上的,这次是自己写的,发现自己尽是细节没搞好
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 const int maxn = 105; 5 struct Point 6 { 7 float x,y; 8 }p[maxn],stack[maxn]; 9 10 double xmult(Point p1,Point p2,Point p0) //cross product 11 { 12 return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); 13 } 14 15 double dis(Point p1,Point p2) //distance 16 { 17 return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y); 18 } 19 20 bool cmp(Point a,Point b) //sort the element of the point besides p[0] 21 { 22 double has; 23 has=xmult(a,b,p[0]); 24 if(has>0) // a is the right of the b 25 return 1; 26 else if((has==0)&& (dis(a,p[0])<dis(b,p[0]))) //sort by distance 27 return 1; 28 else 29 return 0; //a is the left of th b 30 } 31 32 void swap(int r,int s) 33 { 34 Point temp; 35 temp=p[r]; 36 p[r]=p[s]; 37 p[s]=temp; 38 } 39 40 //Graham 41 int Graham(int n) 42 { 43 int i,top,k; 44 Point ans; 45 top=2; 46 if(n<=3) 47 { 48 for(i=0;i<n;i++) 49 stack[i]=p[i]; 50 return n; 51 } 52 k=0; 53 for(i=1;i<n;i++) //find the left-under point 54 if((p[i].y<p[k].y )|| ((p[i].y==p[k].y)&&(p[i].x<p[k].x))) 55 k=i; 56 ans=p[0]; p[0]=p[k]; p[k]=ans; //set the left-under to the p[0] 57 sort(p+1,p+n,cmp); 58 for(i=0;i<=top;i++) 59 stack[i]=p[i]; 60 for(i=top+1;i<n;i++) 61 { 62 if((i+1<n)&&(xmult(p[i],p[i+1],p[0])==0)) //the point in a line 63 continue; 64 while(xmult(p[i],stack[top],stack[top-1])>=0) //if the p[i] is the right of the stack[top] 65 top--; //choose the p[i] 66 stack[++top]=p[i]; 67 } 68 return ++top; 69 } 70 71 bool cmp_xy(Point a,Point b) 72 { 73 if(a.x!=b.x) 74 return a.x<b.x; 75 else 76 return a.y<b.y; 77 } 78 79 int main() 80 { 81 int i,j,t,n,top; 82 cin>>t; 83 while(t--) 84 { 85 cin>>n; 86 for(i=0;i<n;i++) 87 cin>>p[i].x>>p[i].y; 88 top=Graham(n); 89 sort(stack,stack+top,cmp_xy); 90 for(i=0;i<top;i++) 91 cout<<stack[i].x<<" "<<stack[i].y<<endl; 92 } 93 return 0; 94 }