Wannafly挑战赛10-E-小H和棋盘(暴力)

题目描述 
    
小H有一个巨大的棋盘,可以视为无限大的二维坐标系,上面有N个棋子,同一个位置不会有多个棋子。小H给出了如下的定义:
    若存在点(x,y)(x,y∈R),满足对于所有的棋子,都存在一个棋子(可以是本身)和它关于(x,y)对称,则这个棋局是对称的,(x,y)称为对称中心。现在小H最多向棋盘上再下K个棋子,问有多少不同的(x,y),使得存在一种下法,让(x,y)成为对称中心,如果这样的(x,y)有无穷多个,则输出一行-1

    注:棋子只能下在格点处

输入描述:


一行,两个整数N,K
第2~N+1行,每行两个整数,表示一个棋子的位置


1≤N≤105,0≤K≤20,输入所有数的绝对值不超过109

输出描述:

一行,一个整数,意义见题目描述

输入
2 0 
1 1 

-1 -1

输出

1

题解:首先我们将这n个点排序,然后暴力最小和者最大的k个点所能构成的中心对称点即可,因为你最多只能添加k个点使得所有点中心对称,所以你往暴力中间若干点所构成的中心对称点没有意义,这样小的若干点和大的若干点一定不满足,然后我们对于每个暴力出的中心对称点O(n)去找还要添加几个点即可。为防止中心对称点重复,我们用set存一下即可。

#include<set>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 100005
struct node
{
	int x,y;
	bool operator < (const node &b) const
	{
		if(x!=b.x)
			return x<b.x;
		return y<b.y;
	}
	bool operator == (const node &b) const
	{
		if(x==b.x && y==b.y)
			return 1;
		return 0;
	}
	node operator + (const node &b) const
	{
		node c;
		c.x=x+b.x;c.y=y+b.y;
		return c;
	}
}a[maxn];
int n,k,ans;
set<node>s;
int work(node x)
{
	if(s.count(x)) return 0;
	s.insert(x);int i,j=n,cnt=0;
	for(i=1;i<=j;i++)
	{
		while(i<j && x<a[i]+a[j]) j--,cnt++;
		if(x==a[i]+a[j]) j--;
		else cnt++;
	}
	return cnt<=k;
}
int main(void)
{
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&a[i].x,&a[i].y);
	if(k>=n)
	{
		printf("-1\n");
		return 0;
	}
	sort(a+1,a+n+1);
	for(int i=1;i<=k+1;i++)
		for(int j=n-k;j<=n;j++)
			ans+=work(a[i]+a[j]);
	printf("%d\n",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值