• 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;
    }
  • 相关阅读:
    一个简单的进程察看器
    查找素数的程序
    两种动态创建对象的方法
    我对企业管理信息系统的看法
    下定决心,准备买dopod535,做基于M$ smartphone 2003(ce.net 4.2)的开发了
    工作流中对于事务处理的思考
    第二次安装.net2005地感受
    贴一个Microsoft Business Framework的图片上来,可能有些兄弟还不知道。
    SizeOf与Structure与Managed Code
    校园招聘技术面试方面的小题目
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742527.html
Copyright © 2020-2023  润新知