题目大意:给出n个点的编号和坐标,按逆时针方向连接着n个点,按连接的先后顺序输出每个点的编号。
题目思路:Cross(a,b)表示a,b的叉积,若小于0:a在b的逆时针方向,若大于0a在b的顺时针方向。每次都sort一下,找出在当前点逆时针方向的最远的点。数据很小O(N*N*log(N))的复杂度0s AC了……
#include<cstdio> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<cstring> #include<vector> #include<queue> #define INF 0x3f3f3f3f #define MAX 100005 using namespace std; int n,pos,ans[MAX]; struct node { int id,x,y; }point[MAX]; int Dist(int x1,int y1,int x2,int y2) { return sqrt((x1-x2)*(x1-x2)*1.0 + (y1-y2)*(y1-y2)*1.0); } int Cross(int x1,int y1,int x2,int y2,int x3,int y3) { return (x1-x2)*(y1-y3)-(x1-x3)*(y1-y2); } bool cmp(struct node A,struct node B) { int op=Cross(point[pos].x,point[pos].y,A.x,A.y,B.x,B.y); if(op>0) return true; else if(op==0 && Dist(point[pos].x,point[pos].y,A.x,A.y)<Dist(point[pos].x,point[pos].y,B.x,B.y)) return true; return false; } int main() { int T,cnt; scanf("%d",&T); while(T--) { pos=0; cnt=0; memset(ans,0,sizeof(ans)); scanf("%d",&n); scanf("%d%d%d",&point[0].id,&point[0].x,&point[0].y); for(int i=1;i<n;i++) { scanf("%d%d%d",&point[i].id,&point[i].x,&point[i].y); if(point[i].y < point[0].y)//找出起点:左下方的点 swap(point[0],point[i]); else if(point[i].y==point[0].y && point[i].x < point[0].x) swap(point[0],point[i]); } sort(point,point+n,cmp); ans[cnt++]=point[pos++].id; for(int i=1;i<n;i++) { sort(point+i,point+n,cmp); ans[cnt++]=point[pos++].id; } printf("%d ",cnt); for(int i=0;i<cnt;i++) printf("%d%c",ans[i],i==cnt-1?'\n':' '); } return 0; }