链接:点击查看
题意:偶数个点,两点可连成一条线,求平行线最大对数
题解:当时想的时候傻逼了,想成了每次选两个点就是16*15/2 * 14*13/2 .....
其实不需要这样,因为每个点必须要匹配一个的,所以每次搜索,给一个点找其他点即可,复杂度15*13*11.....
斜率用mp记录一下即可 斜率为0 和 不存在的特殊标记
#include<bits/stdc++.h>
using namespace std;
map< int, map<int, int> > mp;
struct node{
int x,y;
}a[20];
int n, vis[20];
int ans;
void dfs(int pos, int step, int sum)
{
if(step==n/2+1)
{
ans=max(ans, sum);
return;
}
if(vis[pos]) dfs(pos+1, step, sum);
else
{
vis[pos]=1;
for(int i=pos+1;i<=n;i++)
{
if(vis[i]) continue;
vis[i]=1;
int kx,ky;
if(a[i].y==a[pos].y)
kx=ky=0;
else if(a[i].x==a[pos].x)
kx=ky=100000;
else
{
ky=a[i].y-a[pos].y;
kx=a[i].x-a[pos].x;
int d=__gcd(abs(kx),abs(ky));
kx/=d;ky/=d;
if(kx<0) kx=-kx,ky=-ky;
}
mp[kx][ky]++;
dfs(pos+1, step+1, sum+mp[kx][ky]-1);
mp[kx][ky]--;
vis[i]=0;
}
vis[pos]=0;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
dfs(1, 1, 0);
printf("%d\n",ans);
return 0;
}