Poj-3304 (叉积判断直线是否过线段)
2017-11-25 07:50
211 查看
题目
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!"); } }
相关文章推荐
- 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments
- POJ 3304 Segments(判断线段和直线是否相交)
- poj 3304 Segments(叉积+直线和线段相交判断)
- POJ 3304 Segments (判断直线和线段是否相交)
- Segments - POJ 3304 (判断直线与线段是否相交)
- poj 3304(利用叉积求是否存在直线与所给线段相交)
- poj 3304 Segments(利用叉积求是否存在直线与所给线段相交)
- poj 3304 判断是否有与所有线段相交的直线
- poj 3304 Segments 【判断是否存在一条直线与所有线段相交】
- POJ 3304 Segments (计算几何、判断直线与线段是否相交)
- poj 3304 判断是否存在一条直线与所有线段相交
- POJ - 3304 :Segments__判断直线和线段是否 相交
- poj 3304 判断线段与直线交
- POJ 3304 判断线段 与 直线 相交
- POJ 3304 Segments (直线和线段相交判断)
- 【POJ - 3304 Segments】 直线线段相交判断
- POJ 3304:Segments 计算几何 是否有直线与所有线段相交
- poj 3304 Segments(判断线段和直线相交)
- POJ 3304 Segments 判断直线与线段相交
- poj 3304 Segments(判断直线与线段相交)