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;
    }
  • 相关阅读:
    php date 时间差
    array_merge 和 + 号的的区别
    apache 添加https后导致http无法访问
    php 获取url
    TP5 事务处理
    LeetCode 每日一题 (盛最多水的容器)
    LeetCode 每日一题 (字符串转换整数 (atoi))
    LeetCode 每日一题(5. 最长回文子串)
    LeetCode 每日一题 (3 无重复字符的最长子串)
    LeetCode 每日一题 (两数相加)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742527.html
Copyright © 2011-2022 走看看