2019亚洲区域赛徐州网络赛 K Center map+贪心

https://nanti.jisuanke.com/t/41393
You are given a point set with nn points on the 2D-plane, your task is to find the smallest number of points you need to add to the point set, so that all the points in the set are center symmetric.

Output
Output a single integer – the minimal number of points you need to add.

样例输入 复制
3
2 0
-3 1
0 -2
样例输出 复制
1
样例解释
For sample 11, add point (5,-3)(5,−3) into the set, the center point can be (1,-1)(1,−1) .

题目大意:给 n n n个点,问至少添加几个点能使得所有的点都中心对称,即能找到一个点 P P P(这个点可以不在集合内),使得集合内任意一个点 i i i,都能在集合内找到一个点 j j j,使得 2 ∗ X p = X i + X j , 2 ∗ Y p = Y i + Y j 2*X_{p}=X_{i}+X_{j},2*Y_{p}=Y_{i}+Y_{j} 2Xp=Xi+Xj,2Yp=Yi+Yj。( i i i可以等于 j j j)。

思路:想明白了其实也是个水题。 O ( n 2 ) O(n^{2}) O(n2)处理出任意两个点的横坐标之和与纵坐标之和(不用除 2 2 2 浮点数不好处理),用 m a p map map记录这个坐标出现的次数,如果两个点是同一个点,则次数 + 1 +1 +1,否则次数 + 2 +2 +2,同时记录次数最大的那个坐标,这就是最优的中心对称点(贪心)。然后再统计一下关于该点没有对称点的点的个数就是答案啦。

#include
#include
#include
#include
#include
#include
#include
#define pr pair
using namespace std;
typedef long long ll;

map<pr,int> m;
int x[1005],y[1005];
bool vis[1005];

int main()
{
	int n;
	scanf("%d",&n);
	pr p,re;
	for(int i=0;i<n;i++)
		scanf("%d%d",&x[i],&y[i]);
	int tmp=0,MAX=0;
	for(int i=0;i<n;i++)
	{
		for(int j=i;j<n;j++)
		{
			p.first=x[i]+x[j],p.second=y[i]+y[j];
			if(j==i)
				tmp=++m[p];
			else
				tmp=(m[p]+=2);
			if(tmp>MAX)
				MAX=tmp,re=p;
		}
	}
	int ans=0;
	bool flag=1;
	for(int i=0;i<n;i++)
	{
		if(vis[i])
			continue;
		flag=1;
		for(int j=0;j<n;j++)
		{
			if(x[i]+x[j]==re.first&&y[i]+y[j]==re.second)
			{
				vis[i]=vis[j]=1;
				flag=0;
				break;
			}
		}
		ans+=flag;
	}
	printf("%d\n",ans);
	return 0;
}

学习了一波 u n o r d e r e d _ m a p unordered\_map unordered_map,这样 500 m s 500ms 500ms就过了 o r z orz orz

#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;

struct point
{
	int x,y;
	bool operator == (const point &a)const
	{
		return x==a.x&&y==a.y;
	}
};

struct point_hash
{
	size_t operator()(const point &p)const
	{
		return hash<int>()(p.x)^hash<int>()(p.y);
	}
};

unordered_map<point,int,point_hash> m;
int x[1005],y[1005];
bool vis[1005];

int main()
{
	int n;
	scanf("%d",&n);
	point p,re;
	for(int i=0;i<n;i++)
		scanf("%d%d",&x[i],&y[i]);
	int tmp=0,MAX=0;
	for(int i=0;i<n;i++)
	{
		for(int j=i;j<n;j++)
		{
			p.x=x[i]+x[j],p.y=y[i]+y[j];
			if(j==i)
				tmp=++m[p];
			else
				tmp=(m[p]+=2);
			if(tmp>MAX)
				MAX=tmp,re=p;
		}
	}
	int ans=0;
	bool flag=1;
	for(int i=0;i<n;i++)
	{
		if(vis[i])
			continue;
		flag=1;
		for(int j=0;j<n;j++)
		{
			if(x[i]+x[j]==re.x&&y[i]+y[j]==re.y)
			{
				vis[i]=vis[j]=1;
				flag=0;
				break;
			}
		}
		ans+=flag;
	}
	printf("%d\n",ans);
	return 0;
}

你可能感兴趣的:(贪心,STL,比赛补题)