zoukankan      html  css  js  c++  java
  • Ural 2036. Intersect Until You're Sick of It 计算几何

    2036. Intersect Until You're Sick of It

    题目连接:

    http://acm.timus.ru/problem.aspx?space=1&num=2036

    Description

    Ural contests usually contain a lot of geometry problems. Many participants do not conceal their discontent with such disbalance. Still, we have decided not to break the tradition and give you an unbalanced contest. Let’s start!
    Consider an iterative process for a set of points on a plane. Every iteration consists of three steps:
    Draw a line through every pair of different points.
    Find all intersections of all pairs of different non-parallel lines.
    Merge the initial set of points with the set of intersection points and go to step one.
    After each iteration, the number of points either increases or stays the same.
    You are given a set of points. Iterations repeat while the number of points increases. How many points will be in the set after the end of this iterative process?

    Input

    The first line contains an integer n (1 ≤ n ≤ 100000). Further input describes n different points. For every point, you are given a pair of integer coordinates whose absolute value does not exceed 108.

    Output

    If the process is infinite, print “oo” (two lowercase Latin letters ‘o’), otherwise print the number of points in the set after the end of the process.

    Sample Input

    4
    0 0
    0 1
    1 0
    1 1

    Sample Output

    5

    Hint

    题意

    给你n个点,然后进行下列操作:

    1.两两点连线

    2.找到所有不平行直线所构成的交点

    3.把所有找到的点和原来的点合并,如果点数增加,再进行1操作;否则break

    输出最后点的数量。

    可能是无限多。

    题解:

    无限多的情况很多,我们来考虑特殊情况,即有解的:

    显然所有点都是在一条直线上,这个答案是n

    显然如果只有一个点不在直线上,这个答案也是n

    有两个点不在直线上,那么答案可能是n,也有可能是n+1.

    基本上情况就这些了,讨论一下,然后求解即可。

    数据:

    Anti-WA #51:
    4
    0 0
    2 0
    1 1
    1 2
    Answer: oo

    Anti-WA #52:
    4
    0 0
    1 2
    2 2
    3 0
    Answer: oo

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N=100010;
    const int inf=1e9;
    
    struct POINT
    {
     long long x;
     long long y;
     POINT(long long a=0, long long b=0) { x=a; y=b;} //constructor
     bool operator<(const POINT &A)const{
        if(A.x==x)return A.y<y;
        return A.x<x;
     }
    };
    long long multiply(POINT sp,POINT ep,POINT op)
    {
     return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
    }
    long long multiply(POINT A,POINT B,POINT C,POINT D)
    {
        long long x1 = A.x-B.x;
        long long y1 = A.y-B.y;
        long long x2 = C.x-D.x;
        long long y2 = C.y-D.y;
        return x1*y2-x2*y1;
    }
    POINT P[N];
    int n;
    
    int solve(POINT st)
    {
        vector<POINT> ans,ret;
        if(st.x==0&&st.y==0)
            {
               return inf;
            }
            for(int i=1;i<=n;i++)
            {
                if(multiply(P[i],st,P[1])!=0) ans.push_back(P[i]);else ret.push_back(P[i]);
            }
            if(ans.size()<=1)
            {
                return n;
            }
            else
            {
                for(int i=2;i<ans.size();i++)
                    if(multiply(ans[0],ans[1],ans[i])!=0) return inf;
                for(int i=0;i<ret.size();i++)
                    if(multiply(ret[i],ans[1],ans[0])==0)
                        return n;
                if(ans.size()>2)
                {
                    return inf;
                }
                else
                {
                    long long t1=multiply(ans[0],st,P[1]),t2=multiply(ans[1],st,P[1]);
                    if(t1>0&&t2>0||t1<0&&t2<0)
                    {
                        return inf;
                    }
                    else
                    {
                        POINT pp;
                        int flag=1,f1=1,f2=1;
                        for(int i=0;i<ret.size();i++)
                        {
                            if(multiply(ret[i],ans[1],ans[0])<0) f1=0;
                            if(multiply(ret[i],ans[1],ans[0])>0) f2=0;
                        }
                        if(f1||f2) flag=0;
                        return n+flag;
                    }
                }
            }
    }
    
    long long X(POINT A,POINT B){
        return A.x*B.y-A.y*B.x;
    }
    long long sq(long long A){
        return A*A;
    }
    long long dis(POINT A,POINT B){
        return sq(A.x-B.x)+sq(A.y-B.y);
    }
    bool ok4(){
        long long tmp = multiply(P[1],P[2],P[3],P[4]);
        if(tmp!=0)return 0;
        tmp = multiply(P[1],P[2],P[3]);
        if(tmp==0)return 0;
        long long dis1 = dis(P[1],P[2]);
        long long dis2 = dis(P[3],P[4]);
        if(dis1!=dis2)return 0;
        return 1;
    }
    bool ok14(){
        long long tmp = multiply(P[1],P[2],P[3]);
        if(tmp==0)return 1;
        long long dis1 = dis(P[1],P[2]);
        long long dis2 = dis(P[3],P[4]);
        if(dis1==dis2)return 1;
        return 0;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d%I64d",&P[i].x,&P[i].y);
        }
        for(int i=2;i<=n;i++)
            P[i].x-=P[1].x,P[i].y-=P[1].y;
        P[1].x=P[1].y=0;
        int tmp=inf;
        if(n<=3)
        {
            printf("%d
    ",n);
            return 0;
        }
        if(n==4){
            sort(P+1,P+1+n);
            do{
                if(ok4()){
                    printf("5
    ");
                    return 0;
                }
            }while(next_permutation(P+1,P+1+n));
            sort(P+1,P+1+n);
            do{
                if(ok14()){
                    printf("4
    ");
                    return 0;
                }
            }while(next_permutation(P+1,P+1+n));
            printf("oo
    ");
            return 0;
        }
        if(n<=5)
        {
            for(int o=2;o<=n;o++)
            {
                tmp=min(tmp,solve(P[o]));
            }
        }
        else
        {
            int flag=0;
            POINT stt;
            stt.x=stt.y=0;
            for(int i=2;i<=6;i++)
            {
                for(int j=i+1;j<=6;j++)
                {
                    for(int k=j+1;k<=6;k++)
                        if(multiply(P[i],P[j],P[1])==0&&multiply(P[i],P[k],P[1])==0)
                        {
                            stt=P[i];
                            flag=1;
                            break;
                        }
                    if(flag) break;
                }
                if(flag) break;
            }
            tmp=solve(stt);
        }
        if(tmp==inf) printf("oo
    ");else printf("%d
    ",tmp);
        return 0;
    }
  • 相关阅读:
    windows anaconda下安装Python的tesserocr库
    windows10上安装docker与碰到的坑
    阿里云centos下部署python flask应用。
    LeetCode--Python合并两个有序链表
    Linux(CentOS)下重置MySQL根(Root)密码,以及远程登录mysql连接IP受限问题解决
    windows下anaconda安装词云wordcloud
    关于selenium使用中谷歌浏览器驱动chromedriver的问题
    LeetCode 184. Department Highest Salary(找出每个部门中最高薪水)
    机器学习七--回归--多元线性回归Multiple Linear Regression
    机器学习六--回归--简单线性回归Simple Linear Regression
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742527.html
Copyright © 2011-2022 走看看