POJ

来源:互联网 发布:药品查询软件下载 编辑:程序博客网 时间:2024/05/21 08:57

点我看题

题意:给出一系列的线段,问是否存在一条直线,使得所有的线段在这条直线上的投影会交于一点。

分析:看完这个题,第一反应就想能不能转化为直线与线段的交,然后想去理清这个问题,画个图看看。


其中a为我们要找的直线,但是我们发现要判断是否存在一条a这样的直线是一件很困难的事情,因为我们没办法利用题目给的条件(n条线段的坐标),那么观察这个图,我们可以知道如果a存在,那么就一定存在与a垂直的一条直线b且b与其他n条线段有一个交点,那么整个题就转化为了问咱是否存在一条与其他n条线段都相交的线段。

那么我们可以一一枚举线段上这些点的两个端点形成一条直线,如果满足上述条件,则一定存在。

那么如何判断一条直线去某一线段是否相交呢那就要利用点的叉乘了,也就是线段Q1Q2的两个端点一定要在直线P1P2的左右两边,如下图


那么一定要满足(P1-Q1)×(p2-Q1)*(P1-Q2)×(P2-Q2) <= 0 才能表示直线与线段相交。

参考代码:

#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define eps 1e-8const int maxn = 1e2+5;int n;struct Point{    double x,y;    Point(){}    Point( double xx, double yy)    {        x = xx;        y =yy;    }    Point operator - ( const Point &p)const    {        return Point(x-p.x,y-p.y);    }    //点的叉乘    double operator ^ ( const Point &p)const    {        return x*p.y-y*p.x;    }    //点的乘法(通常用于求两点距离)    double operator * ( const Point p)const    {        return x*p.x+y*p.y;    }};struct Line{    Point a,b;    Line(){}    Line( Point aa, Point bb)    {        a = aa;        b = bb;    }};Line line[maxn];//计算叉乘(p2-p1)*(p3-p1)double xmult( Point p1, Point p2, Point p3){    return (p2-p1)^(p3-p1);}//判断两点之间的距离double dist( Point p1, Point p2){    return sqrt((p2-p1)*(p2-p1));}int sgn( double x){    if( fabs(x) < eps)        return 0;    if( x < 0)        return -1;    return 1;}//判断直线和线段是否相交 l1为直线,l2为线段bool SegInterLine( Line l1, Line l2){//    if( xmult(l1.a,l2.a,l1.b)*xmult(l1.a,l1.b,l2.b) < 0)//这也是可以的,kuangbin的写法//        return false;//        return true;    if( xmult(l2.a,l1.a,l1.b)*xmult(l2.b,l1.a,l1.b) <= 0)        return true;    return false;}//判断p1p2是否与其他的线段相交bool check( Line l){    if( sgn(dist(l.a,l.b)) == 0)//两个点重合        return false;    for( int i = 0; i < n; i++)    {        //判断直线和线段是否相交//        if( xmult(p1,line[i].a,p2)*xmult(p1,p2,line[i].b) < 0)//            return false;        if( !SegInterLine(l,line[i]))            return false;    }    return true;}int main(){    int T;    scanf("%d",&T);    while( T--)    {        scanf("%d",&n);        double xa,ya,xb,yb;        for( int i = 0; i < n; i++)        {            scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);            line[i] = Line(Point(xa,ya),Point(xb,yb));        }        bool flag = false;        for( int i = 0; i < n; i++)        {            for( int j = 0; j < n; j++)            {                if( check(Line(line[i].a,line[j].a)) || check(Line(line[i].a,line[j].b)) || check(Line(line[i].b,line[j].a)) || check(Line(line[i].b,line[j].b)))                {                    flag = true;                    break;                }            }        }        if( flag)            puts("Yes!");        else            puts("No!");    }    return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 换sim卡通讯录怎么办 麦芒4开不了机怎么办 麦芒5开不了机怎么办 麦芒6针丢了怎么办 麦芒6扬声器坏了怎么办 华为手机2s太卡怎么办 华为麦芒6网速慢怎么办 华为麦芒5太卡怎么办 小米note3拍照反应慢怎么办 华为刷机后还要账号密码怎么办 刷机后忘记华为账号和密码怎么办 荣耀7x耗电快怎么办 小米2s死机后怎么办? 电信合约卡不想用了怎么办 vivo合约机掉了怎么办 华为合约机丢了怎么办 两年合约机掉了怎么办 电信合约机丢了怎么办 s8合约机坏了怎么办 合约机的卡掉了怎么办 移动合约机屏幕碎了怎么办 5s用不了电信卡怎么办 vivo手机4g信号差怎么办 电信dns辅服务器未响应怎么办 笔记本wifi下载速度慢怎么办 苹果wifi下载速度慢怎么办 小米手机wifi下载速度慢怎么办 苹果8plus上网慢怎么办 小米5c死机了怎么办 苹果x自拍反方向怎么办 硅胶手机壳出油怎么办 指环扣松了怎么办图解 塑料放久了发粘怎么办 橡胶时间久了粘怎么办 胶的手机套变黄怎么办 手机壳硅胶变黄怎么办 硅胶手机壳大了怎么办 硅胶手机壳变大了怎么办 硅胶手机壳有点大怎么办 硅胶手机壳粘手怎么办 透明手机壳变黄怎么办?