HDU 4462
http://acm.hust.edu.cn/vjudge/contest/123462#problem/J
题目大意:
有一片N*N的田地,里面有M个田被乌鸦吃掉了,现在可以在这些被吃
掉的田地里放置稻草人,没个地方的稻草人可以吓走乌鸦的范围半径是r1到rn
(半径可以不相等)
问至少有多少个稻草人才能保护好田地(覆盖整个田)
这题几个坑第一个被吃掉的地方可以不用保护,给出的半径不是圆而是一个菱形
因为数据范围很小所以枚举稻草人,搜索就可以啦。
#include<stdio.h>
#include<string.h>
#define MAX 60
struct tree
{
int x,y;
int r;
}p[20];
int min(int a,int b)
{
return a>b?b:a;
}
int n;
int vis[MAX][MAX]; //记录稻草人位置
int map[MAX][MAX];
int t[MAX]; //记录第i个稻草人是否被使用过
int cover[MAX][MAX]; //判断是否被覆盖
int ans;
int m;
int abs(int a)
{
return a>0?a:-a;
}
int dis(tree q,int x,int y)
{
return (abs(q.x-x)+abs(q.y-y));
}
int vj() //判断是否完全覆盖
{
memset(cover,0,sizeof(cover));
int i,j,k;
for(i=0;i<m;i++)
{
if(t[i])
{
for(j=1;j<=n;j++)
{
for(k=1;k<=n;k++)
{
if(dis(p[i],j,k)<=p[i].r)
{
cover[j][k]=1;
//printf("!!%d %d\n",i,j);
}
}
}
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(!cover[i][j]&&!vis[i][j])
{
return 0;
}
}
return 1;
}
void dfs(int cov,int ss) //暴搜
{
if(ss>ans)
{
return;
}
if(cov==m+1)
{
if(vj())
ans=min(ans,ss);
return;
}
t[cov]=1; //枚举
dfs(cov+1,ss+1);
t[cov]=0;
dfs(cov+1,ss);
}
int main()
{
while(scanf("%d",&n)==1&&n)
{
memset(vis,0,sizeof(vis));
memset(t,0,sizeof(t));
scanf("%d",&m);
int i;
for(i=0;i<m;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
vis[p[i].x][p[i].y]=1;
}
ans=10000000;
for(i=0;i<m;i++)
scanf("%d",&p[i].r);
dfs(0,0);
if(ans==10000000)
printf("-1\n");
else
printf("%d\n",ans);
}
}