题意:
- 给你平面的一个点集,然后要你从y坐标最小的点开始以水平方向向下一个点连线,每次只能直走或左转,问你最多能走多少点?
题解:极角排序
- 先以y为基准排序,找到y最小的点最为起始点。
- 每次以基准点进行极角排序,找到写一个点,一次类推。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;
int const N = 100 + 10;
typedef struct Point{
int num;
double x,y;
Point(){};
Point(double x,double y):x(x),y(y){};
Point operator - (const Point& p)const{
return Point(x - p.x,y - p.y);
}
double operator ^ (const Point& p)const{
return x * p.y - y * p.x;
}
}Vector;
Point p[N],st;
bool cmp1(Point a,Point b){
return a.y < b.y || a.y == b.y && a.x < b.x;
}
bool cmp2(Point a,Point b){
double t = (a - st) ^ (b - st);
return t > 0 || t == 0 && a.x < b.x;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%lf%lf",&p[i].num,&p[i].x,&p[i].y);
}
sort(p,p + n,cmp1);
for(int i=1;i<n;i++){
st = p[i-1]; //以p[i-1]为基准
sort(p + i,p + n,cmp2);
}
printf("%d",n);
for(int i=0;i<n;i++)
printf(" %d",p[i].num);
printf("\n");
}
return 0;
}