题目:题目链接
题意:找逆时针螺旋线最多能连几个点
分析:贪心使用一些几何上的极角排序,凸包的应用,每次都连最外面的点即可。每次找到一个当前点curp,除了第一
次是对数组按纵坐标排序得出外,剩下的均按极角排序。使用一个ans数组记录链接的每一个点:
代码:
#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#include <map>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <functional>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cassert>
#include <bitset>
#include <stack>
#include <ctime>
#include <list>
#define INF 0x7fffffff
#define max3(a,b,c) (max(a,b)>c?max(a,b):c)
#define min3(a,b,c) (min(a,b)<c?min(a,b):c)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
struct Point
{
int x, y;
int index;
};
Point curp;
int Cross(const Point &o, const Point &a, const Point &b)
{
return (a.x - o.x)*(b.y - o.y) - (b.x - o.x)*(a.y - o.y);
}
bool CmpByy(const Point &a, const Point &b)
{
return a.y < b.y;
}
double dis(const Point &a, const Point &b)
{
return sqrt(double((a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y)));
}
bool CmpBYAngle(const Point &a, const Point &b)
{
int res = Cross(curp, a, b);
if(res > 0)
return true;
else if(res < 0)
return false;
else
{
double dis1 = dis(a, curp);
double dis2 = dis(b, curp);
if(dis1 < dis2)
return true;
else
return false;
}
}
Point point[55];
int main()
{
int M;
scanf("%d", &M);
int n;
while(M--)
{
scanf("%d", &n);
for(int i = 0; i < n; ++i)
scanf("%d%d%d", &point[i].index, &point[i].x, &point[i].y);
sort(point, point+n, CmpByy);
curp = point[0];
int ans[1000];
mem(ans, 0);
int cnt = 0;
int pos = 0;
ans[pos++] = curp.index;
//cout << " " << curp.index ;
for(int i = 1; i < n; i++)
{
sort(point+i,point+n,CmpBYAngle);
curp = point[i];
ans[pos++] = curp.index;
cnt++;
//cout << " " << curp.index;
}
printf("%d", pos);
for(int i = 0; i < pos; ++i)
printf(" %d", ans[i]);
printf("\n");
}
return 0;
}