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>