Poj-3304 (叉积判断直线是否过线段)
来源:互联网 发布:dotacoko淘宝 编辑:程序博客网 时间:2024/05/16 19:24
题目
http://poj.org/problem?id=3304
题意大概就是给一些线段,问能不能找到一条直线使得这些线段在直线上的投影的交不为空。
线段数不大于100。
分析
- 要是投影的交不为空,那么就是至少有一条垂直于那个直线的直线能经过所有线段。
- 而且可以说明,只要有解,那么肯定可以有个解经过某两个端点。(因为直线就是被这些端点限制住的,在边界处肯定是端点)
- 然后就枚举端点弄出一条直线,再判断一下是否经过所有选段即可。
程序
#include <cstdio>#include <cmath>using namespace std;double k1,k2;int n,T,ok;struct node{double x,y;} U[1000],V[1000];bool equ(node A,node B){return abs(A.x-B.x)<=0.00000001 && abs(A.y-B.y)<=0.00000001;}bool Equ(double x,double y){return abs(x-y)<=0.00000001;}double cheng(node v1,node v2){return v1.x*v2.y-v2.x*v1.y;}bool check(node u,node v){ if (equ(u,v)) return 0; for (int i=1; i<=n; i++){ if (equ(u,U[i]) || equ(u,V[i]) || equ(v,U[i]) || equ(v,V[i])) continue; k1=cheng((node){U[i].x-u.x,U[i].y-u.y},(node){U[i].x-v.x,U[i].y-v.y}); k2=cheng((node){V[i].x-u.x,V[i].y-u.y},(node){V[i].x-v.x,V[i].y-v.y}); if (k1*k2>0) return 0; } return 1;}int main(){ for(scanf("%d",&T); T--; ok=0){ scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%lf%lf%lf%lf",&U[i].x,&U[i].y,&V[i].x,&V[i].y); for (int i=1; i<=n && !ok; i++) for (int j=i; j<=n && !ok; j++){ ok=check(U[i],U[j])||check(U[i],V[j])||check(V[i],U[j])||check(V[i],V[j]); } puts(ok?"Yes!":"No!"); }}
提示
- 我觉得也可以枚举一个端点,假设直线过这个端点,然后利用其它线段来限制住这条直线的斜率,看看最后斜率的可取区间是否为空,可是不知道为什么过不了,代码放下面,也请帮忙看看吧。
#include <cstdio>#include <cmath>#include <algorithm>using namespace std;struct node{double x,y;} U[20000],V[20000];double Max,Min,mn,mx,k1,k2,k3,k4;int n,ok,T;double K(node A,node B){ if (A.x==B.x) return 99999999999999999999999999999.0; return (A.y-B.y)/(A.x-B.x);}bool equ(node A,node B){return abs(A.x-B.x)<=0.00000001 && abs(A.y-B.y)<=0.00000001;}bool dy(double x,double y){return x-y>0.0001;}bool xy(double x,double y){return y-x>0.0001;}bool check(node O){ Min=-99999999999999999999999999999.0; Max=99999999999999999999999999999.0; for (int i=1; i<=n; i++) if(!equ(O,U[i]) && !equ(O,V[i])){ k1=K(O,U[i]); k2=K(O,V[i]); mn=min(k1,k2),mx=max(k1,k2); if (dy(mn,Max) || xy(mx,Min)) return 0; if (xy(mx,Max)) Max=mx; if (dy(mn,Min)) Min=mn; if (dy(Min,Max)) return 0; } return 1;}int main(){ for (scanf("%d",&T); T--;){ ok=0; scanf("%d",&n); for (int i=1; i<=n; i++) scanf("%lf%lf%lf%lf",&U[i].x,&U[i].y,&V[i].x,&V[i].y); for (int i=1; i<=n && !ok; i++) if (check(U[i]) || check(V[i])) ok=1; puts(ok?"Yes!":"No!"); }}
阅读全文
0 0
- Poj-3304 (叉积判断直线是否过线段)
- POJ - 3304 :Segments__判断直线和线段是否 相交
- POJ 3304 Segments (判断直线和线段是否相交)
- POJ 3304 Segments(判断线段和直线是否相交)
- 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments
- POJ 3304 判断直线与线段相交
- POJ 3304 判断线段 与 直线 相交
- poj 3304 判断直线与线段相交
- poj 3304 判断线段与直线交
- POJ 3304 判断线段和直线相交
- POJ 3304 直线与线段相交判断
- poj 3304 判断是否有与所有线段相交的直线
- poj 3304 Segments 【判断是否存在一条直线与所有线段相交】
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- 51nod 判断线段是否相交 poj Segments直线与多条线段相交
- poj 3304 Segments(贪心+直线是否与线段相交!)
- poj 3304 Segments(判断直线与线段相交)
- poj 3304 Segments(判断线段和直线相交)
- 欢迎使用CSDN-markdown编辑器
- BZOJ3828: [Poi2014]Criminals
- Poj-1696 (叉积)
- Mac下安装SpringBoot的CLI(命令行界面)
- BZOJ3829: [Poi2014]FarmCraft
- Poj-3304 (叉积判断直线是否过线段)
- 数据库Sqlite-WAL模式
- go:chan分为阻塞和非阻塞
- [学习笔记]Python_字符串,元祖,字典
- 计算几何笔记
- 数字图像处理matlab版第二章
- 【拜小白opencv】40-形态学滤波5——形态学梯度(基本梯度、内部梯度、外部梯度、方向梯度)
- 谁是医疗AI领域的第一梯队?
- bzoj 4513: [Sdoi2016]储能表 数位dp