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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天谕账号被冻结怎么办 促黄体生成素低怎么办 地暖家里太干燥怎么办 剑灵摧毁了东西怎么办 想打嗝打不出来怎么办 孩子满100天要怎么办 宝宝吃奶粉过敏了怎么办 1岁宝宝不喝奶粉怎么办 母乳不够宝宝不喝奶粉怎么办 宝宝吃奶粉上火了怎么办 我小孩不喝奶粉怎么办 2岁宝宝不喝奶粉怎么办 婴儿吃奶粉上火了怎么办 100天的宝宝咳嗽怎么办 40天的小孩咳嗽怎么办 40天的婴儿咳嗽怎么办 50天的婴儿咳嗽怎么办 宝宝20天感冒了怎么办 1个月宝宝咳嗽怎么办 40天的宝宝干咳怎么办 百天的宝宝咳嗽怎么办 50天的孩子咳嗽怎么办 百天宝宝咳嗽有痰怎么办 1岁半宝宝拉肚子怎么办 百天的宝宝拉肚子怎么办 激战2帧数三十多怎么办 太受欢迎了怎么办txt微 太受欢迎了怎么办网盘 太受欢迎了怎么办微盘 我太受欢迎了该怎么办h 我太受欢迎了该怎么办1 卡培他滨副作用怎么办 究极风暴4卡怎么办 脸下垂法令纹深怎么办 20岁有法令纹怎么办 3个月婴儿铅超标怎么办 一岁宝宝铅超标怎么办 小樱死了 佐助怎么办 平板玩游戏闪退怎么办 手机玩游戏闪退怎么办 天天爱消除闪退怎么办