您的位置:首页 > 其它

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!");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: