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;
}