zoukankan      html  css  js  c++  java
  • HDU5738

    题意就是要找一条直线上的点,注意有重点;

    组合数公式从0取到n为2n,注意运用就好

    C(0,N)+C(1,N)+....+C(N,N)=2N

    C(R,N)+C(R+1,N)=C(R+1,N+1)

    数点的时候每个点有两种情况(出现,不出现),如果与第i个点相同的有m个,那么对于只有相同点时,ans=pqow(2,m)-1【减去都消失的情况】;一次共线的有n个,ans =pqow(2,m)*(pqow(2,n)-1)。 

    注意运用第一个公式,因为第i个点必定要用到,其他的点用法有两种,只用i的重点和不止用i的重点

    只用i的重点相当于从1开始取组合数

    不止用i的重点则重点可以从0开始取组合数,非重点则从1开始取

    #include <stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<iostream>
    #include<map>
    using namespace std;
    typedef long long LL;
    map<pair<LL,LL>,int>vis;
    const int mod=1e9+7;
    int t,n;
    struct st{
    LL x,y;
    }num[1005];
    bool cmp(st a,st b){
    if(a.x==b.x)
        return a.y<b.y;
    else
        return a.x<b.x;
    }
    LL gcd(LL a,LL b){
    return b?gcd(b,a%b):a;
    }
    
    LL qpow(LL a,LL b){
        if(b<0)
            return 0;
        a%=mod;
        LL ans = 1;
        while(b) {
            if(b&1) ans = (ans * a) % mod;
            b >>= 1;
            a = (a * a) % mod;
        }
        return ans;
      }
    
    
    int main()
    {
        freopen("in.txt","r",stdin);
     cin>>t;
     while(t--){
    
        scanf("%d",&n);
        int i,j;
        for( i=1; i<=n; i++)
            scanf("%lld%lld",&num[i].x,&num[i].y);
        sort(num+1,num+1+n,cmp);
        LL ans=0;
        for( i=1; i<=n; i++){
            vis.clear();
            int res=1;
            for( j=i+1; j<=n; j++){
            if(num[j].x==num[i].x&&num[i].y==num[j].y)
                res++;
            else{
            LL dx=num[i].x-num[j].x;
            LL dy=num[i].y-num[j].y;
            LL gg=gcd(dx,dy);
            if(gg!=0){
                dx/=gg;
                dy/=gg;
            }
        
            vis[make_pair(dx,dy)]++;
            }
            }
            if(res>1){
            ans+=(qpow(2,res-1)-1)%mod;//第一种只用这个点的情况,用到当前遍历的点和与其重合的点
            ans%=mod;
            }
         // cout<<ans<<" "<<i<<endl;
    
    
                for(map<pair<LL,LL>,int>::iterator it = vis.begin();it!=vis.end();it++)
                {
                    LL cnt=(it->second);
                    ans = (ans+((qpow(2,cnt)-1)*(qpow(2,res-1)))%mod)%mod;//用重点和其他点的情况
                }
    
    
        }
        cout<<ans<<endl;
     }
    }
  • 相关阅读:
    用 Web 实现一个简易的音频编辑器
    TypeScript教程
    他的独,殇情沉醉
    重新拎一遍js的正则表达式
    网络流
    Xmind最新的安装与破解教程
    adb的端口号5037被占用的解决方法
    使用Fiddler模拟弱网测试教程
    web的前台、后台、前端、后端
    常见面试笔试题
  • 原文地址:https://www.cnblogs.com/shimu/p/5698541.html
Copyright © 2011-2022 走看看