https://nanti.jisuanke.com/t/41393
看了clarification,说每个点都不相同,这就好做了
我们把所有可能的中心点求出来,然后看哪个数量最多就行了。
注意到clarification中所说的,如果一个点就在重心对称点上,那么不需要加一个新点。
所以一个点的中心可能再他与其他n个点(包括他本身)的中心上。
我们把每个点与其他n个点连成线的中点求出来,然后排序,找最多的那个,由于每个点都是不同的,那么一个点与其他n个点的连线的中点都是不同的,那么一堆相同的中点中,必然都属于不同的点连出去的线的中点(u,v之间会求出两个相同的中点,但分别属于u和v),那么最多的数量,就当于最多这么多点不需要加新点。
#include<bits/stdc++.h>
#define maxl 2010
using namespace std;
int n,cnt,ans;
struct node
{
int x,y,id1,id2;
bool operator == (const node &b) const
{
return x==b.x && y==b.y;
}
bool operator < (const node &b)const
{
if(x==b.x)
return y<b.y;
else
return x<b.x;
}
}a[maxl],b[maxl*maxl];
inline bool cmp(const node &a,const node &b)
{
if(a.x==b.x)
return a.y<b.y;
return a.x<b.x;
}
inline void prework()
{
cnt=0;
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
x=x*2;y=y*2;
a[i].x=x;a[i].y=y;
}
cnt=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
{
++cnt;
b[cnt].x=(a[i].x+a[j].x)/2;
b[cnt].y=(a[i].y+a[j].y)/2;
b[cnt].id1=i;b[cnt].id2=j;
}
for(int i=1;i<=n;i++)
{
++cnt;
b[cnt].x=a[i].x;
b[cnt].y=a[i].y;
}
sort(b+1,b+1+cnt,cmp);
}
inline void mainwork()
{
int mx=0,tot=1;
for(int i=2;i<=cnt;i++)
if(b[i]==b[i-1])
tot++;
else
{
if(tot>mx)
mx=tot;
tot=1;
}
if(tot>mx)
mx=tot;
ans=n-mx;
}
inline void print()
{
printf("%d\n",ans);
}
int main()
{
while(~scanf("%d",&n))
{
prework();
mainwork();
print();
}
return 0;
}