http://acm.pku.edu.cn/JudgeOnline/problem?id=1696
贪心一下就可以了,每次选择最佳点。然后将点设为新的起点。数据很弱。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <math.h>
using namespace std;
#define FOR(i,s,e) for (int (i)=(s); (i) < (e);i++)
struct POINT
{
double x;
double y;
POINT(double a=0, double b=0) { x=a; y=b;} //constructor
bool operator<(POINT a){return atan2(y - 50, x - 50) < atan2(a.y - 50, a.x - 50); }
};
struct LINESEG
{
POINT s;
POINT e;
LINESEG(POINT a, POINT b) { s=a; e=b;}
LINESEG() { }
};
const double INF = 1E20;
const double EP = 1E-9;
const int MAXV = 300;
const double PI = 3.14159265;
double multiply(POINT sp,POINT ep,POINT op)
{
return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
}
double dis(POINT a, POINT b)
{
return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
int n;
POINT p[250];
POINT start;
int num;
bool sign[250];
int ans[250];
int main()
{
// freopen("in.txt","r",stdin);
int t ;
int end;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
FOR(i,0,n)
{
int k;
scanf("%d %lf %lf",&k,&p[i].x, &p[i].y);
if (i == 0 || p[i].y < start.y)
start = p[i];
}
if (n == 1)
{
printf("1 1\n");
continue;
}
start.x= 0;
memset(sign,false,sizeof(sign));
num = 0;
while (1)
{
int max = -1;
int max_help = 0;
int sum = 0;
FOR(i,0,n)
if (!sign[i])
{
sum = 0;
FOR(j,0,n)
if (i != j && !sign[j] && (multiply(p[i],p[j],start)>=0) )
sum++;
if (sum > max || (sum == max && (dis(p[max_help],start) > dis(p[i],start))) )
{
max_help = i;
max = sum;
}
}
if (max<= 0)
break;
ans[num++] = max_help;
sign[max_help] = true;
start = p[max_help];
}
printf("%d",num+1);
FOR(i,0,num)
printf(" %d",ans[i]+1);
FOR(i,0,n)
if (!sign[i])
{printf(" %d",i+1);break;}
printf("\n");
}
return 0;
}