UVA 361 Cops and Robbers(凸包应用)
来源:互联网 发布:暖气管道钥匙 淘宝 编辑:程序博客网 时间:2024/04/30 07:00
UVA 361 Cops and Robbers(凸包应用)
https://vjudge.net/problem/UVA-361
题意:
有c个警察,r个强盗,和o个市民.他们都用二维平面的一个点表示.如果一个市民被3个警察构成的三角形包围,那么他safe.否则,如果这个市民被3个强盗构成的三角形包围,那么他是robbed. 如果该市民既不在警察包围内也不在强盗包围内,那么它是neither.
现在要你求每个市民的情况.
分析:
如果直接暴力枚举所有可能的警察构成的三角形,然后再用每个市民的点去判断是否被包含,那么明显超时.其实有下列结论:
如果某市民被一个警察构成的三角形包围 充要条件 该市民一定在所有警察构成的凸包内.(在边上也算)
上面结论同样适用于强盗.所以我们只需要分别求出警察和强盗构成的凸包,然后判断一个市民点在两个凸包内的情况即可.
注意:本题只要初始警察的个数>=3,那么就算警察构成的凸包形状是一个点或一条线(n点共点,n点共线), 此时如果市民在该点或线上,就也算市民safe. 但是如果初始警察数<=2的话,直接可以不用求凸包,警察不能包围任何人.(强盗情况也是一样的)
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const double eps=1e-10;int dcmp(double x){ if(fabs(x)<eps) return 0; return x<0?-1:1;}struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} bool operator==(const Point& B)const { return dcmp(x-B.x)==0 && dcmp(y-B.y)==0; } bool operator<(const Point &B)const { return dcmp(x-B.x)<0 || (dcmp(x-B.x)==0 && dcmp(y-B.y)<0); }};typedef Point Vector;Vector operator-(Point A,Point B){ return Vector(A.x-B.x,A.y-B.y);}double Dot(Vector A,Vector B){ return A.x*B.x+A.y*B.y;}double Cross(Point A,Point B){ return A.x*B.y-A.y*B.x;}int ConvexHull(Point *p,int n,Point *ch){ sort(p,p+n); n=unique(p,p+n)-p; int m=0; for(int i=0;i<n;i++) { while(m>1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])<0) m--;//注意<=0 ch[m++]=p[i]; } int k=m; for(int i=n-2;i>=0;i--) { while(m>k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])<0) m--; ch[m++]=p[i]; } if(n>1) m--; return m;}bool InSegment(Point P,Point A,Point B){ return dcmp(Cross(A-B,P-A))==0 && dcmp(Dot(A-P,B-P))<=0;}bool IsPointInPolygon(Point p,Point *poly,int n){ int wn=0; for(int i=0;i<n;++i) { if(InSegment(p, poly[(i+1)%n], poly[i]) ) return true; int k=dcmp( Cross(poly[(i+1)%n]-poly[i], p-poly[i] ) ); int d1=dcmp( poly[i].y-p.y ); int d2=dcmp( poly[(i+1)%n].y-p.y ); if(k>0 && d1<=0 && d2>0) ++wn; if(k<0 && d2<=0 && d1>0) --wn; } if(wn!=0) return true; return false;}/***以上为刘汝佳模板***/const int maxn=500+5;Point P[maxn],Q[maxn];Point p[maxn],q[maxn];int main(){ int n,m,k; int cas=1; while(scanf("%d%d%d",&n,&m,&k)==3) { if(n==0&&m==0&&k==0)break;printf("Data set %d:\n",cas++); for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);for(int i=0;i<m;i++)scanf("%lf%lf",&q[i].x,&q[i].y);int n1=ConvexHull(p,n,P);int m1=ConvexHull(q,m,Q);for(int i=0;i<k;i++){Point s;scanf("%lf%lf",&s.x,&s.y);if(n>=3 && IsPointInPolygon(s,P,n1)) printf(" Citizen at (%.0lf,%.0lf) is safe.\n",s.x,s.y); else if(m>=3 && IsPointInPolygon(s,Q,m1)) printf(" Citizen at (%.0lf,%.0lf) is robbed.\n",s.x,s.y); else printf(" Citizen at (%.0lf,%.0lf) is neither.\n",s.x,s.y);}printf("\n"); } return 0;}
阅读全文
0 0
- UVA 361 Cops and Robbers(凸包应用)
- UVA 361 Cops and Robbers(凸包应用)
- uva 361 - Cops and Robbers(凸包)
- uva 361 - Cops and Robbers(凸包)
- UVA 361 Cops and Robbers
- UVa 361 - Cops and Robbers
- UVA 361 || Cops and Robbers (点是否在凸包内
- UVa 1616 Caravan Robbers
- UVa - 1616 - Caravan Robbers
- UVA 1616 - Caravan Robbers
- UVA 1616 Caravan Robbers
- Caravan Robbers UVA
- uva 1277 Cops and Thieves(完成阻击所需要的最少人数)
- ural 1277. Cops and Thieves【最小割】
- ural 1277. Cops and Thieves【最小割】
- URAL 1277 Cops and Thieves 最小割
- UVA 218 Moth Eradication(凸包应用)
- Robbers
- HDFS定时上传日志的Shell案列
- poj3295(构造法?)
- 在MVC中引用EasyUI
- 51Nod 1010 只包含因子2 3 5的数
- Linux学习(十二):gcc编译和gdb调试
- UVA 361 Cops and Robbers(凸包应用)
- PascalTriangle
- Android修改屏幕密度
- 多字段搜索 (二)
- HDU 1005-Number Sequence(找规律)
- 厚黑学 札记
- 疯狂Java讲义笔记 整形与浮点型
- Android 获取文件夹大小,删除等操作
- Android性能优化之渲染优化