HDU 5738 共线点集

http://acm.hdu.edu.cn/showproblem.php?pid=5738

 

题意:一个定义,要求一个点集中所以点共线、或者都在一个点。问有多少的这样的集合。

 

思路:2016多校一个题目,方法是对点排序然后对剩下的点斜率排序一下子再(或者map瞎搞一下,没有排序快)。公式就是取当前枚举点和得到的相同k的点,排列组合一下子很简单,记得重复点要提前处理一下子。

 

比赛坑在不排序瞎搞各种WA各种T。。。我对几何一无所知。。

 

代码:

 

 

#include <iostream>
#include <cmath>
#include <cstdio>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
const int mo=1e9+7;
const double inf=1e100;
pair<int,int> P[1005];
long long Qpow(long long a,int n){
    long long ans = 1;
    while(n){
        if(n&1) ans = (ans*a)%mo;
        a = (a*a)%mo;
        n >>= 1;
    }
    return ans;
}
double L[1005];

int main()
{
    int t;
    cin>>t;
    while(t--){
        int n,x,y;
        long long ret=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            scanf("%d%d",&P[i].first,&P[i].second);
        }
        sort(P,P+n);
        for(int i=0;i<n;i++){
            int cnt=1;
            while(i+1<n&&P[i]==P[i+1]){
                i++;cnt++;
            }
            ret=(ret+Qpow(2,cnt)-cnt-1)%mo;
            int nu=0;
            for(int j=i+1;j<n;j++){
                if(P[j].first==P[i].first) L[nu++]=inf;
                else L[nu++]=(double)(P[i].second-P[j].second)/(P[i].first-P[j].first);
            }
            sort(L,L+nu);
            for(int j=0;j<nu;j++){
                int zxl=1;
                while(j+1<nu&&L[j+1]==L[j]){
                    j++;zxl++;
                }
                ret=(ret+(Qpow(2,zxl)-1)*(Qpow(2,cnt)-1)%mo)%mo;
            }
        }
        printf("%lld\n",ret);
    }
    return 0;
}

/**
10
7
0 0
0 0
1 2
2 4
3 6
1 -2
2 -4   ans  42 <span style="font-family: Arial, Helvetica, sans-serif;">**/</span>



posted @ 2016-07-22 19:37  zhangxianlong  阅读(132)  评论(0编辑  收藏  举报