凸包问题
来源:互联网 发布:nodejs于java跨域传值 编辑:程序博客网 时间:2024/05/16 10:13
#include<cstdio>#include<algorithm>#include<fstream>#include<cstring>#include<iostream>using namespace std;const int MAX=550;struct point{ int x; int y; int v; int i; int tmp;} Ini[MAX],res[MAX],p[MAX];bool flag[MAX];int ans[MAX];bool cmp(point A,point B) //同速度的排序,仍然是找x小的和y小的;{ if(A.y==B.y)return A.x<B.x; return A.y<B.y;}bool cmp1(point A,point B)//排序从大到小,以及同速度的x小点,同速度同x的y小点;这里是对原数组的排序;{ if(A.v>B.v)return true; if(A.v==B.v) { if(A.x<B.x)return true; if(A.x==B.x&&A.y<B.y)return true; } return false;}int cross(point A,point B,point C)//点积;{ return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);}int Graham(point *p,int n){ //if (n<3)return n; sort(p,p+n,cmp); memset(flag,false,sizeof(flag)); int i; int top=0; for(i=0; i<n; i++) { while(top>=2&&cross(res[top-2],res[top-1],p[i])<0)/*构造下边界,若不在凸包上则将点出栈;(这里是判断如果点积小于0继续循环,知道找到凸包的点,而=0即共线情况也是凸包的点,也要跳出,所以这里不能取等)知道满足凸包条件跳出循环,然后记录;*/ { top--; } res[top]=p[i]; //res数组存下在凸包上的点; res[top].tmp=i; //记录入栈点的编号;
top++; } for(i=0;i<top;i++) flag[res[i].tmp]=true; int t=top+1; for(i=n-2; i>=0; i--) //i>=0 { while(top>=t&&cross(res[top-2],res[top-1],p[i])<0) //构造上边界;
top--; if(!flag[i]) res[top++]=p[i]; //满足条件且不在已构造的凸包内; //if(i==0)top--; } /*for(i=0; i<top; i++) printf("$%d %d\n",res[i].x,res[i].y);*/ return top;//返回凸包上点的个数;}int main(){ int n; int i,j; //ifstream cin("A.txt"); int __case=0; while(cin>>n&&n) { for(i=0; i<n; i++) { cin>>Ini[i].x>>Ini[i].y>>Ini[i].v; Ini[i].i=i;//标记位置id } sort(Ini,Ini+n,cmp1);//排序找出速度最大点(前面的好几位都是速度最大点),并按坐标排序; //cout<<Ini[i-1].x<<Ini[i-1].y; int tmp=0; for(i=0; i<n; i++) { if(Ini[0].v>0&&Ini[0].v==Ini[i].v) tmp++; else break; }//筛出最大速度的点; memset(ans,0,sizeof(ans)); point po; for(i=0,j=0;i<tmp;i++) { po=Ini[i]; //flag=1; if(i<tmp-1&&Ini[i+1].x==po.x&&Ini[i+1].y==po.y)//找重点 ,因为已经按排序过,所以重点一点是出现在相邻点之间; { while(i<tmp-1&&Ini[i+1].x==po.x&&Ini[i+1].y==po.y) { ans[Ini[i].i]=-1; i++; } ans[Ini[i].i]=-1; //重点则不可能无限,先标记掉; } p[j++]=po;//保留所有的符合的点,注意此时重点也要留下一个点。 } int m=Graham(p,j);//传入数组时不仅要有地址,还要传入长度;此时传入的数组是已经去完重点的,在函数中就不用判断了; printf("Case #%d: ",++__case); for(i=0; i<m; i++) { if(!ans[res[i].i])ans[res[i].i]=1;//如果不是重点且在凸包上,则使其为1; } for(i=0; i<n; i++) { if(ans[i]==1)printf("1"); else printf("0"); } printf("\n"); } return 0;}
0 0
- 凸包问题
- 凸包问题
- poj2187 凸包问题
- 凸包问题
- ACM -- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题-蛮力法
- 凸包问题
- 凸包问题
- 凸包问题
- 凸包问题
- ACM:凸包问题
- hdu 1392 凸包问题
- 题目1078:二叉树遍历(根据前序和中序遍历结果,获得后序遍历)
- hdu 4405(期望)
- 基于HBase的存储引擎 Honeycomb
- Matlab图像处理1——imgadjust
- WebRTC源代码探索之旅——多线程篇(7 - 2)
- 凸包问题
- Html表单学习经典例子
- 2014.8.15模拟赛【公主的朋友】
- 分割哈师大分割是否合适地方
- WebRTC源代码探索之旅——多线程篇(7 - 3)
- iOS面试题之加载单张图片到底会不会崩溃?
- C++怪谈——C++多态“失灵”
- Triangle - CodeForces 407A 水题
- WebRTC源代码探索之旅——多线程篇(8)