开始用求凸包的方法做的代码。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<map>
#include<set>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
using namespace std;
/*********************************************************************/
const int MAX_NUM = 50+10;
struct plant{
int id,x,y;
double cos;
}p[MAX_NUM];
int sk[MAX_NUM],skLen;
double GetCosWithX (plant& a, plant& b){return (b.x-a.x) / sqrt( pow(a.x-b.x,2)+pow(a.y-b.y,2) );}
double min_2 (int x,int y) {return x<y?x:y;}
int CrossMuti (plant a,plant b){return a.x*b.y-a.y*b.x;}
bool cmpPlant (plant a,plant b){
if (a.cos>b.cos)
return true;
else if (a.cos==b.cos)
return a.x<=b.x&&a.y<=b.y;
else
return false;
}
void HandleStack (int i)
{
if (skLen<=3){
sk[skLen++]=i;
return;
}
plant ab,bc;
while (1)
{
if (skLen<2){printf ("handle error\n");return;}
ab.x=p[sk[skLen-1]].x-p[sk[skLen-2]].x;
ab.y=p[sk[skLen-1]].y-p[sk[skLen-2]].y;
bc.x=p[i].x-p[sk[skLen-1]].x;
bc.y=p[i].y-p[sk[skLen-1]].y;
if (CrossMuti(ab,bc)>=0){
sk[skLen++]=i;
return;
}
else
--skLen;
}
}
/*********************************************************************/
int main()
{
int t,n;
scanf ("%d",&t);
while (t--)
{
scanf ("%d",&n);
int minY=1000,minX=1000,minID;
//set<point,int>
for (int i=0;i<n;i++){
scanf ("%d%d%d",&p[i].id,&p[i].x,&p[i].y);
if (minY>p[i].y){
minY=p[i].y;
minX=p[i].x;
minID=i;
}
else if (minY==p[i].y && minX>p[i].x){
minX=p[i].x;
minID=i;
}
}
p[minID].cos=1.0;
for (int i=0;i<n;i++){
if (i==minID) continue;
p[i].cos=GetCosWithX (p[minID],p[i]);
}
sort (p,p+n,cmpPlant);
/*for (int i=0;i<n;i++)
printf ("%d ",p[i].id);
printf ("\n");*/
skLen=0;
sk[skLen++]=0;
for (int i=1;i<n;i++){
HandleStack (i);
/*for (int j=0;j<skLen;j++)
printf ("%d ",p[sk[j]].id);
printf ("\n");*/
}
for (int j=0;j<skLen;j++)
printf ("%d ",p[sk[j]].id);
printf ("\n");
}
return 0;
}