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;
    }
  • 相关阅读:
    时间控件My97DatePicker,实现时间的选择,具体运用
    OnClientClick事件和验证控件同时用的时候,会有问题
    根据Eval()函数绑定的值,来显示GridView中的控件的方法
    打印部分页面内容(Javascript)
    U盘装系统中bios怎么设置USB启动(图文教程)
    TextBox控件只允许输入数字(转)
    JS模态窗体的运用,以及相关注意事项(有用到window.returnValue)
    控件TextBox与验证控件相结合产生的控件(运用)
    linq 实现动态 orderby(根据参数名排序)
    yii 多个数据库链接
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5742527.html
Copyright © 2011-2022 走看看