zoukankan      html  css  js  c++  java
  • poj 3304 题解

    题意:给出n条线段,判断是否存在一条直线,使所有线段在该直线上的投影有公共点,是则输出“Yes!”,否则输出“No!”

      1<=n<=100,多组测试数据

    题解:题目可转化为是否存在一条直线与所有线段都相交(这条直线与题目中所要求的直线垂直)。假如存在这样一条直线,我们显然可以通过移动这条直线使得它与某两条线段的某两个端点相交,则直接枚举线段端点,判断是否符合条件即可,复杂度O(n3)

    特判:距离小于1e-8的点视为重合、n=1时一定成功

    写的时候犯了不少错误,最后的代码乱糟糟的

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    #define rep(i,a,b) for(int i=a;i<=b;++i)
    
    const double eps=1e-8;
    
    struct point{
        double x,y;
        point(){}
        point (double a,double b): x(a),y(b) {}
    
        friend point operator + (const point &a,const point &b){
            return point(a.x+b.x,a.y+b.y);
        }
    
        friend point operator - (const point &a,const point &b){
            return point(a.x-b.x,a.y-b.y);
        }
    
        friend bool operator == (const point &a,const point &b){
            return (abs(a.x-b.x)<eps && abs(a.y-b.y)<eps);
        }
    
    };
    
    inline double det(point a,point b) {return a.x*b.y-a.y*b.x;}
    inline bool line_cross_segment(point s,point t,point a,point b)
    {
        return !(det(s-a,t-a)*det(s-b,t-b)>eps);
    }
    
    point s[200][2];
    double sx,sy,tx,ty;
    int t,n;
    
    
    bool test(int x,int y)
    {
        point ts,tt;
        bool flag=false;
        rep(i,0,1)
        {
            rep(j,0,1) if (!(s[x][i]==s[y][j]))
                {
                    flag=true;
                    ts=s[x][i];tt=s[y][j];
                    rep(k,1,n)
                        if (!line_cross_segment(ts,tt,s[k][0],s[k][1]))
                        {
                            flag=false;
                            break;
                        }
                    if (flag) break;
                }
            if (flag) break;
        }
        if (flag) return true;
            else return false;
    }
    
    int main()
    {
        scanf("%d",&t);
        bool flag;
        while (t--)
        {
            scanf("%d",&n);
            flag=false;
            rep(i,1,n)
                {
                    scanf("%lf%lf%lf%lf",&sx,&sy,&tx,&ty);
                    s[i][0]=point(sx,sy);s[i][1]=point(tx,ty);
                }
            if (n<=2) {printf("Yes!
    ");continue;}
            rep(i,1,n)
            {
                rep(j,i+1,n)
                    if(test(i,j)) {flag=true;break;}
                if (flag) break;
            }
            if (flag) printf("Yes!
    ");else printf("No!
    ");
        }
        return 0;
    }
  • 相关阅读:
    LINQ标准查询操作符及例子(转载)
    Winform Combox 下拉模糊匹配
    在RowDataBound事件中取值的几种方法 转载
    shell脚本作业练习题8.6
    7.31.... 简单的python代码
    shell 脚本——第一节课 bash的基本特性
    shell 脚本——第二节课 重定向和管道符
    730
    应用范例:解析 Yahoo 奇摩股市的各档股票资讯HtmlAgilityPack
    微软一个罕为人知的无敌命令
  • 原文地址:https://www.cnblogs.com/terra/p/7001881.html
Copyright © 2011-2022 走看看