标签:each plane enter body nal com dice its height
Space Ant
Input
Output
Sample Input
2 10 1 4 5 2 9 8 3 5 9 4 1 7 5 3 2 6 6 3 7 10 10 8 8 1 9 2 4 10 7 6 14 1 6 11 2 11 9 3 8 7 4 12 8 5 9 20 6 3 2 7 1 6 8 2 13 9 15 1 10 14 17 11 13 19 12 5 18 13 7 3 14 10 16
Sample Output
10 8 7 3 4 9 5 6 2 1 10 14 9 10 11 5 12 8 7 6 13 4 14 1 3 2
题目大意就是,在二维平面是找出一条路径,满足:
1.只能向左弯折;
2.弯折的地方只能是给定的点集中的点;
3.路径不能与之前的有相交;
4.要求经过给定的点越多越好.
这一题用到的是凸包的思想,却不是凸包.先说结论:我们每次以前一次到达的点为最下方的点(同时为基准点),旋转这个图,下一个到达的点就是新图中最最右边,且距离x轴最近的点(先满足前一个要求).
那么这个其实就是运用到凸包的排序思想,对于上述的条件,其实只需要运用叉积做cmp来排序就好啦.由于n很小,所以这题就能稳稳地过了.
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 #include<iostream> 6 #include<stack> 7 using namespace std; 8 int n,nowpos; 9 struct point{int x,y,index;}a[105]; 10 point operator - (point u,point v){point ret; ret.x=u.x-v.x,ret.y=u.y-v.y; return ret;} 11 int dis(point u,point v){return (u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y);} 12 int cross(point u,point v){return u.x*v.y-v.x*u.y;} 13 inline int read(){ 14 int x=0,f=1; char ch=getchar(); 15 while (ch<‘0‘||ch>‘9‘){if (ch==‘-‘) f=-f; ch=getchar();} 16 while (ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); 17 return x*f; 18 } 19 bool cmp(const point &P,const point &Q){ 20 return cross(P-a[nowpos],Q-a[nowpos])>0||cross(P-a[nowpos],Q-a[nowpos])==0&&dis(a[nowpos],P)<dis(a[nowpos],Q); 21 } 22 int main(){ 23 for (int T=read(); T; T--){ 24 n=read(),memset(a,0,sizeof a); 25 for (int i=1; i<=n; i++) a[i].index=read(),a[i].x=read(),a[i].y=read(); 26 for (int i=2; i<=n; i++) if (a[i].y<a[1].y||a[i].y==a[1].y&&a[i].x<a[1].x) swap(a[1],a[i]); 27 nowpos=1; 28 for(int i=2; i<=n; i++){ 29 sort(a+i,a+n+1,cmp); nowpos++; 30 } 31 printf("%d",n); 32 for (int i=1; i<=n; i++) printf(" %d",a[i].index); 33 puts(""); 34 } 35 return 0; 36 }
标签:each plane enter body nal com dice its height
原文地址:http://www.cnblogs.com/whc200305/p/7183891.html