知道怎么计数很简单,但知道怎么想出简单的计数很难。
固定两个点算集合的个数,这样既好写,又不用记纵截距,map里的东西又少。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #define maxn 1050 #define mod 1000000007 using namespace std; int n,ans=0,tab[maxn],x[maxn],y[maxn],tot=0; struct point { int x,y; point (int x,int y):x(x),y(y) {} point () {} }p[maxn]; map <pair<int,int>,int> mp; int gcd(int a,int b) { if (!b) return a; return gcd(b,a%b); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]); tab[0]=1;for (int i=1;i<=1000;i++) tab[i]=tab[i-1]*2%mod; for (int i=1;i<=n;i++) { tot=0;int cls=0; for (int j=i+1;j<=n;j++) { if ((x[j]==x[i]) && (y[j]==y[i])) cls++; else p[++tot]=point(x[j]-x[i],y[j]-y[i]); } mp.clear(); for (int j=1;j<=tot;j++) { int nx,ny,d; nx=p[j].x;ny=p[j].y; if ((nx<0) || ((nx==0) && (ny<0))) nx=-nx,ny=-ny; d=gcd(nx,ny);nx/=d;ny/=d; ans+=tab[mp[make_pair(nx,ny)]+cls];if (ans>=mod) ans-=mod; mp[make_pair(nx,ny)]++; } ans+=tab[cls]-1;if (ans>=mod) ans-=mod; } printf("%d ",ans); return 0; }