usaco Closed Fences
来源:互联网 发布:淘宝车牌选号 编辑:程序博客网 时间:2024/05/16 16:14
本来这道题目却被不想写的,因为方法有点麻烦。
不过最后还是耐下性子写了。呜……
思路是挺简单的。
设观察位置为A,BC为多边形上的一条边。若有边挡住了A点的视线,刚更新A当前的视野。
如下图:
此时视野为BC1
此时视野为B1C
此时被完全挡住,没有视野。
代码如下:
/*ID: guo geerPROG: fence4LANG: C++*/#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>using namespace std;#define les 1e-6struct Point{int x, y;};Point P[300],ob;int res[300];double x,y;//交点 double cross(double x1,double y1,double x2,double y2,double x,double y){ return (x1-x)*(y2-y)-(x2-x)*(y1-y);}int intersection(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){ if(cross(x2,y2,x3,y3,x1,y1)==0&&cross(x2,y2,x4,y4,x1,y1)==0) return 0; if(cross(x2,y2,x3,y3,x1,y1)*cross(x2,y2,x4,y4,x1,y1)<=les&&cross(x4,y4,x1,y1,x3,y3)*cross(x4,y4,x2,y2,x3,y3)<=les) return 1; return 0;}int isInTriangle(double x1,double y1,double x2,double y2,double x3,double y3,double x,double y){ double x0,y0; x0=(x1+x2+x3)/3; y0=(y1+y2+y3)/3; if(cross(x1,y1,x0,y0,x2,y2)*cross(x1,y1,x,y,x2,y2)<=les) return 0; if(cross(x2,y2,x0,y0,x3,y3)*cross(x2,y2,x,y,x3,y3)<=les) return 0; if(cross(x3,y3,x0,y0,x1,y1)*cross(x3,y3,x,y,x1,y1)<=les) return 0; return 1;}void PointOfIntersection(double x1,double y1,double x2,double y2,double x3,double y3,double x4,double y4){ double k1,k2,b1,b2; if(x1==x2&&x3!=x4) { k2=(y3-y4)/(x3-x4); b2=y3-k2*x3; x = x1; y = k2*x1+b2; } else if(x1!=x2&&x3==x4) { k1=(y2-y1)/(x2-x1); b1=y1-k1*x1; x = x3; y = k1*x3+b1; } else if(x1!=x2&&x3!=x4) { k1=(y2-y1)/(x2-x1); b1=y1-k1*x1; k2=(y3-y4)/(x3-x4); b2=y3-k2*x3; x = (b1-b2)/(k2-k1); y = k1*x+b1; }}int main(){ freopen("fence4.in","r",stdin); freopen("fence4.out","w",stdout); int n,Count; while(scanf("%d", &n) == 1) { memset(res, 0, sizeof(res)); Count = 0; scanf("%d %d",&ob.x,&ob.y); for(int i=0; i<n; i++) scanf("%d %d",&P[i].x,&P[i].y); for(int i=0; i<n; i++) { if(cross(ob.x,ob.y,P[i].x,P[i].y,P[(i+1)%n].x,P[(i+1)%n].y)==0) continue; //printf("--------%d-----------\n",i); bool flag = true; double ax,ay,bx,by; ax=P[i].x,ay=P[i].y; bx=P[(i+1)%n].x,by=P[(i+1)%n].y; for(int j=(i+1)%n; j!=i; j=(j+1)%n) { if(cross(ob.x,ob.y,P[j].x,P[j].y,P[(j+1)%n].x,P[(j+1)%n].y)==0) continue; if(intersection(P[j].x,P[j].y,P[(j+1)%n].x,P[(j+1)%n].y,ob.x,ob.y,ax,ay)==1) { if(intersection(ob.x,ob.y,bx,by,P[(j+1)%n].x,P[(j+1)%n].y,P[j].x,P[j].y)==1) { //if(P[i].x==5&&P[i].y==50) //printf("j=%d 1\n",j); flag = false; break; } else if(isInTriangle(ob.x,ob.y,ax,ay,bx,by,P[j].x,P[j].y)==1) { //if(P[i].x==5&&P[i].y==50) //printf("j=%d 2\n",j); PointOfIntersection(ob.x,ob.y,P[j].x,P[j].y,ax,ay,bx,by); ax=x; ay=y; } else if(isInTriangle(ob.x,ob.y,ax,ay,bx,by,P[(j+1)%n].x,P[(j+1)%n].y)==1) { //if(P[i].x==5&&P[i].y==50) //printf("j=%d 3\n",j); PointOfIntersection(ob.x,ob.y,P[(j+1)%n].x,P[(j+1)%n].y,ax,ay,bx,by); ax=x; ay=y; } } else if(intersection(P[j].x,P[j].y,P[(j+1)%n].x,P[(j+1)%n].y,ob.x,ob.y,bx,by)==1) { if(isInTriangle(ob.x,ob.y,ax,ay,bx,by,P[j].x,P[j].y)==1) { //if(P[i].x==5&&P[i].y==50) //printf("j=%d 4\n",j); PointOfIntersection(ob.x,ob.y,P[j].x,P[j].y,ax,ay,bx,by); bx=x; by=y; } else if(isInTriangle(ob.x,ob.y,ax,ay,bx,by,P[(j+1)%n].x,P[(j+1)%n].y)==1) { //if(P[i].x==5&&P[i].y==50) //printf("j=%d 5\n",j); PointOfIntersection(ob.x,ob.y,P[(j+1)%n].x,P[(j+1)%n].y,ax,ay,bx,by); bx=x; by=y; } } } //printf("%d %d %d %d %lf %lf %lf %lf\n",P[i].x,P[i].y,P[i+1].x,P[i+1].y,ax,ay,bx,by); if(ax==bx&&ay==by) { continue; } if(flag==true) { Count ++; res[i]=1; } } printf("%d\n",Count); for(int i=0; i<n-2; i++) if(res[i]==1) { printf("%d %d %d %d\n",P[i].x,P[i].y,P[i+1].x,P[i+1].y); } if(res[n-1]==1) printf("%d %d %d %d\n",P[0].x,P[0].y,P[n-1].x,P[n-1].y); if(res[n-2]==1) printf("%d %d %d %d\n",P[n-2].x,P[n-2].y,P[n-1].x,P[n-1].y); } return 0;}
- usaco Closed Fences
- USACO Closed Fences 解题报告
- USACO 3.4 Closed Fences (fence4)
- usaco 3.4 Closed Fences 计算几何
- USACO Section 3.4 Closed Fences - 暴力枚举..
- Closed Fences
- USACO section 3.4 Closed Fences(计算几何+叉积+二分)
- 【USACO题库】3.4.1 Closed Fences闭合的栅栏
- USACO Training 3.4.1 Closed Fences闭合的栅栏 题解与分析
- usaco Riding the Fences
- USACO6.5.2 Closed Fences(fence4)
- USACO: Chap3 Riding the Fences
- usaco 3.2 Riding The Fences
- usaco 3.3 Riding the Fences
- usaco java Riding the Fences
- usaco 3.3 Riding the Fences
- usaco 5.2.2 Electric Fences
- USACO Electric Fences 解题报告
- 杭电 2087 KMP算法的应用 求出现次数
- JSTL遍历Map
- 88. Blood will have blood. 血债血偿
- TortoiseSVN日常使用指南(二)
- TortoiseSVN日常使用指南(一)
- usaco Closed Fences
- 获取ini配置文件各节的名称 For C#
- jdbc简单原理操作
- 在运行SSIS包时,如何动态更新变量值
- 可更新订阅的事务复制错误:列名 'msrepl_tran_version' 无效
- 了解SQL Server触发器及触发器中的事务
- windows 多线程编程的几点经验 (防止死锁)
- 项目管理软件 基于Scrum 迭代增量开发的 禅道 ZenTaoPMS
- SQL Server 同步复制中的MSSQL_REPL-2147201001問題處理