POJ 1066 Treasure Hunt(浮点判断线段交点)
来源:互联网 发布:无线的访客网络 编辑:程序博客网 时间:2024/06/05 03:06
http://poj.org/problem?id=1066
在下图中,
求解从四边到中间终点至少要穿过几堵墙。
浮点数据的线段判断是否相交。另外,我们需要设置四边的起点,不是直接遍历每个坐标,而是找已有的交点。(有一种贪心的意思)。
#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double eps=1e-6;struct point { double x,y;};struct edge{ point u,v;}eg[40];double min(double q1,double q2){ return q1-q2<eps?q1:q2;}double max(double q1,double q2){ return q1-q2>eps?q1:q2;}bool on(point a,point b,point c){ if(c.x>=min(a.x,b.x)&&c.x<=max(a.x,b.x)&&c.y>=min(a.y,b.y)&&c.y<=max(a.y,b.y)) return 1; return 0;}double multi(point p0,point p1,point p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}bool cross(point p1,point p2,point p3,point p4){ bool tag=0; double r1=multi(p3,p4,p1),r2=multi(p3,p4,p2); double r3=multi(p1,p2,p3),r4=multi(p1,p2,p4); if(r1*r2<eps&&r3*r4<eps) tag=1; else if(fabs(r1)<eps&&on(p3,p4,p1))tag=1; else if(fabs(r2)<eps&&on(p3,p4,p2))tag=1; else if(fabs(r3)<eps&&on(p1,p2,p3))tag=1; else if(fabs(r4)<eps&&on(p1,p2,p4)) tag=1; return tag;}int main(){ //freopen("cin.txt","r",stdin); int n; while(cin>>n){ point u,v; for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&eg[i].u.x,&eg[i].u.y,&eg[i].v.x,&eg[i].v.y); } scanf("%lf%lf",&eg[n].u.x,&eg[n].u.y); if(n==0){ puts("Number of doors = 1"); continue; } int ans=n; for(int i=0;i<n;i++){ //就选择交点作为另一个端点 eg[n].v.x=eg[i].u.x; eg[n].v.y=eg[i].u.y; int sum=0; for(int j=0;j<n;j++){ if(cross(eg[n].u,eg[n].v,eg[j].u,eg[j].v)) sum++; } ans=ans<sum?ans:sum; eg[n].v.x=eg[i].v.x; eg[n].v.y=eg[i].v.y; sum=0; for(int j=0;j<n;j++){ if(cross(eg[n].u,eg[n].v,eg[j].u,eg[j].v)) sum++; } ans=ans<sum?ans:sum; } printf("Number of doors = %d\n",ans); } return 0;}
事实上,他还能代码优化:
#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double eps=1e-6;struct point { double x,y;};struct edge{ point u,v;}eg[40];double multi(point p0,point p1,point p2){ return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);}bool cross(point p1,point p2,point p3,point p4){ bool tag=0; double r1=multi(p3,p4,p1),r2=multi(p3,p4,p2); double r3=multi(p1,p2,p3),r4=multi(p1,p2,p4); if(r1*r2<eps&&r3*r4<eps) tag=1; //如果是端点接触相交 r1*r2趋近于0 tag=1 return tag;}int main(){ //freopen("cin.txt","r",stdin); int n; while(cin>>n){ point u,v; for(int i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&eg[i].u.x,&eg[i].u.y,&eg[i].v.x,&eg[i].v.y); } scanf("%lf%lf",&eg[n].u.x,&eg[n].u.y); if(n==0){ puts("Number of doors = 1"); continue; } int ans=n; for(int i=0;i<n;i++){ //就选择交点作为另一个端点 eg[n].v.x=eg[i].u.x; eg[n].v.y=eg[i].u.y; int sum=0; for(int j=0;j<n;j++){ if(cross(eg[n].u,eg[n].v,eg[j].u,eg[j].v)) sum++; } ans=ans<sum?ans:sum; eg[n].v.x=eg[i].v.x; eg[n].v.y=eg[i].v.y; sum=0; for(int j=0;j<n;j++){ if(cross(eg[n].u,eg[n].v,eg[j].u,eg[j].v)) sum++; } ans=ans<sum?ans:sum; } printf("Number of doors = %d\n",ans); } return 0;}
0 0
- POJ 1066 Treasure Hunt(浮点判断线段交点)
- POJ 1066 Treasure Hunt 判断线段相交(求交点个数)
- poj 1066 Treasure Hunt(判断线段相交)
- POJ 1066 Treasure Hunt(线段相交判断)
- POJ 1066 Treasure Hunt(线段相交判断)
- poj 1066 Treasure Hunt(判断线段相交)
- poj 1066 Treasure Hunt(判断线段相交)
- poj 1066 Treasure Hunt(判断线段相交)
- POJ 1066 Treasure Hunt (线段相交)
- poj 1066 Treasure Hunt (线段交)
- POJ 1066 Treasure Hunt 判断两线段是否相交
- POJ 1066 Treasure Hunt (判断线段相交个数)
- uva 754 Treasure Hunt?! (线段位置判断并且求交点)
- Poj 1066 Treasure Hunt && Nyoj 83 迷宫寻宝(二)判断线段相交
- 1066 Treasure Hunt (判断线段相交)
- POJ 1066 Treasure Hunt(线段相交&&转换)
- POJ 1066 Treasure Hunt(转化线段相交)
- POJ 1066 Treasure Hunt (思维、线段相交)
- Select选择后,刷新页面保存上一次选择内容
- 使用XML文件输入和输出和YAML文件 目标 你会发现以下问题的答案: 如何打印和阅读文本条目文件和OpenCV使用YAML或XML文件? 如何为OpenCV做同样的数据结构?
- Android加壳native实现
- jquery全局ajax参数详细执行分析-$.ajax竟然可以这样用!
- node环境搭建安装nmp
- POJ 1066 Treasure Hunt(浮点判断线段交点)
- 傅立叶变换- 阐释与--理解
- SQL中 patindex函数的用法
- fopen,fopen_s,_wfopen_s与_fsopen, _wfsopen的区分
- 原码,反码,补码
- php扩展geoIP的使用
- 【JS学习笔记】JS基础中:流程控制
- 4016: [FJOI2014]最短路径树问题 点分治
- LeetCode Sqrt(x)