长度宽度都为n的正方形田地种满了玉米,其中一些点的玉米被野怪吃掉了变成了空地... 在不同的空地安插一个稻草人,可以保护与这个点曼哈顿距离小于ki的点。给出空地的坐标,问最少要多少个稻草人可以保护所有非空地的点。一眼看上去就知道是个水题..开始被题意坑了好久,以为要把整个正方向全覆盖,结果WA到死。最后发现只要覆盖非空地的点就行了....空地数量不超过10,直接枚举1024种状态,或者直接DFS都行吧。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <memory.h>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <map>
#include <stack>
using namespace std;
typedef long long ll;
struct node
{
int x,y,range;
}dc[15];
int n,m,p,q,x,y;
int tt;
int ans;
bool on[15];
bool site[55][55];
bool check(int x,int y)
{
if (x>=1 && y>=1 && x<=n && y<=n) return true;
return false;
}
void go(int x1,int y1,int x2,int y2,int fx,int fy)
{
while(x1!=x2 && y1!=y2)
{
if (check(x1,y1)) site[x1][y1]=true;
x1+=fx;
y1+=fy;
}
}
bool work(int sta)
{
memset(on,false,sizeof on);
memset(site,false,sizeof site);
for (int i=1; i<=m; i++)
site[dc[i].x][dc[i].y]=true;
int x1,x2,x3,x4,y1,y2,y3,y4;
for (int i=1; i<=m; i++)
{
on[i]=sta&1;
sta>>=1;
}
for (int i=1; i<=m; i++)
{
if (on[i])
{
site[dc[i].x][dc[i].y]=true;
for (int j=1; j<=dc[i].range; j++)
{
x1=dc[i].x-j;
x2=x4=dc[i].x;
x3=dc[i].x+j;
y1=y3=dc[i].y;
y2=dc[i].y-j;
y4=dc[i].y+j;
go(x1,y1,x2,y2,1,-1);
go(x2,y2,x3,y3,1,1);
go(x3,y3,x4,y4,-1,1);
go(x4,y4,x1,y1,-1,-1);
}
}
}
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
if (!site[i][j]) return false;
return true;
}
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d",&n) && n)
{
scanf("%d",&m);
for (int i=1; i<=m; i++)
scanf("%d%d",&dc[i].x,&dc[i].y);
for (int i=1; i<=m; i++)
scanf("%d",&dc[i].range);
bool ok=false;
int res=0,ans=1000;
for (int sta=0; sta<(1<<m); sta++)
{
res=0;
ok=false;
if (work(sta))
{
ok=true;
}
if (ok)
{
for (int i=1; i<=m; i++)
{
if (on[i]) res++;
}
ans=min(ans,res);
}
}
if (ans<=10) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}