HDU4462.Scaring the Birds(枚举子集+二进制表示状态)

https://vjudge.net/contest/369905#problem/D
题意:
在给定位置可以放稻草人,然后稻草人在一定范围内可以保护草地,要求至少要设置多少个稻草人才可以保护所有的草地
解题思路:
因为稻草人数量不大于10,所以可以直接枚举
稻草人的使用状况可以用二进制1到1<<k-1来表示,然后对于每一种状态进行n*n的讨论即可
特别要注意,稻草人的位置不需要覆盖,所以当k>=n *n的情况下要输出0

#include<cstdio>
#include<iostream>
#include<string.h>
using namespace std;
int n,k;
int ans=9999;
int vis[55][55];
int num[15];
int min(int a,int b)
{
	return a<b?a:b;
}
struct node
{
	int x,y,r;
}a[15];
bool judge(int x,int y,node a)
{
	if(abs(x-a.x)+abs(y-a.y)<=a.r)
		return true;
	else
		return false;
}
int main()
{
	while(scanf("%d",&n)!=EOF){
		if(n==0)
			break;
		ans=9999;
		memset(vis,0,sizeof(vis));
		scanf("%d",&k);
	for(int i=1;i<=k;i++)
	{
		scanf("%d%d",&a[i].x,&a[i].y);
		vis[a[i].x][a[i].y]=1;
	}
	for(int i=1;i<=k;i++)
		scanf("%d",&a[i].r);
	//特别注意k>=n*n的情况
	if(k>=n*n)
	{
		printf("0\n");
		continue;
	}
	int s=(1<<k)-1;
	for(int i=1;i<=s;i++)
	{
		memset(num,0,sizeof(num));
		int cnt=0;
		for(int j=0;j<k;j++)
			if(i&(1<<j))
				num[cnt++]=j+1;
		int res=0;
		for(int ii=1;ii<=n;ii++)
		{
			for(int jj=1;jj<=n;jj++)
			{
				if(vis[ii][jj]){
					res++;
					continue;
				}
				for(int kk=0;kk<cnt;kk++)
				{
					if(judge(ii,jj,a[num[kk]]))
					{
						res++;
						break;
					}
				}
			}
		}
		if(res==n*n)
		{
			ans=min(cnt,ans);
		}
	}
	if(ans!=9999)
		printf("%d\n",ans);
	else
		printf("-1\n");
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Buyi.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值