zoukankan      html  css  js  c++  java
  • hdu-5738 Eureka(组合计数+极角排序)

    题目链接:

    Eureka

    Time Limit: 8000/4000 MS (Java/Others)  

      Memory Limit: 65536/65536 K (Java/Others)


    Problem Description
     
    Professor Zhang draws n points on the plane, which are conveniently labeled by 1,2,...,n. The i-th point is at (xi,yi). Professor Zhang wants to know the number of best sets. As the value could be very large, print it modulo 109+7.

    A set P (P contains the label of the points) is called best set if and only if there are at least one best pair in P. Two numbers u and v (u,vP,uv) are called best pair, if for every wPf(u,v)g(u,v,w), where f(u,v)=(xuxv)2+(yuyv)2−−−−−−−−−−−−−−−−−−−√ and g(u,v,w)=f(u,v)+f(v,w)+f(w,u)2.
     
    Input
     
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first line contains an integer n (1n1000) -- then number of points.

    Each of the following n lines contains two integers xi and yi (109xi,yi109) -- coordinates of the i-th point.
     
    Output
     
    For each test case, output an integer denoting the answer.
     
    Sample Input
     
    3
    3
    1 1
    1 1
    1 1
    3
    0 0
    0 1
    1 0
    1
    0 0
     
    Sample Output
     
    4
    3
    0
     
    题意:
     
    给 n个点,大于等于2个在同一条直线上的点可以构成一个集合,问你现在有多少个集合;
     
    思路:
     
    先把给的这些点按坐标排序,然后按顺序选一个点i,这个点i作为一定选到集合里面的点,然后再选枚举这个点之后的点j,形成一条直线,再看这条直线上没有被访问过的点k(i<k<n&&k!=j)有多少;假设有num个,那么就可以形成包含点i的集合2^num-1,同时这些点里面有重合的点,还有就是为降低复杂度,要用极角排序,但是最后判断的时候极角排序的精度好像又不太够,所有我就直接用原来的坐标判断的;
     
    AC代码:
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    
    using namespace std;
    
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    
    typedef  long long LL;
    
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const int inf=1e9;
    const int N=1e5+10;
    const int maxn=500+10;
    const double eps=1e-9;
    
    int n,vis[1010];
    LL fx,fy,f[1010];
    struct node
    {
        double ang;
        LL x,y;
    }po[1010],temp[1010];
    int cmp1(node a,node b)
    {
        return a.ang<b.ang;
    }
    int cmp(node a,node b)
    {
        if(a.y==b.y)return a.x<b.x;
        return a.y<b.y;
    }
    
    int main()
    {
            int t;
            read(t);
            f[0]=1;
            For(i,1,1008)
            {
                f[i]=f[i-1]*2%mod;
            }
            while(t--)
            {
                read(n);
                For(i,1,n)
                {
                    read(po[i].x);read(po[i].y);
                }
                sort(po+1,po+n+1,cmp);
                LL ans=0;
                For(i,1,n-1)
                {
                    int cnt=0,s=0;
                    For(j,i+1,n)
                    {
                        if(po[j].x==po[i].x&&po[j].y==po[i].y){s++;continue;}
                        temp[++cnt].ang=atan2(po[j].y-po[i].y,po[j].x-po[i].x);
                        temp[cnt].x=po[j].x;
                        temp[cnt].y=po[j].y;
                    }
                    sort(temp+1,temp+cnt+1,cmp1);
                    fx=po[i].x,fy=po[i].y;
    				int d=0;
                    for(int j=1;j<=cnt;)
                    {
                        int k,num=s+1;
                        for(k=j+1;k<=cnt;k++)
                        {
                            if((temp[k].y-fy)*(temp[j].x-fx)!=(temp[j].y-fy)*(temp[k].x-fx))break;
                            num++;
                        }
                        j=k;
                        ans=(ans+f[num]-1+mod)%mod;
                        d++;
                    }
                    ans=(ans-(LL)(d-1)*(f[s]-1+mod)%mod+mod)%mod;
                }
                cout<<ans<<endl;
            }
            return 0;
    }
    

      

  • 相关阅读:
    18软工实践-第三次作业-结对项目1
    结对作业之代码规范
    ALPHA(7)
    ALPHA(6)
    ALPHA(五)
    404 Note Found 现场编程
    ALPHA(四)
    ALPHA冲刺(三)
    ALpha冲刺(二)
    ALPHA 冲刺(一)
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5693133.html
Copyright © 2011-2022 走看看