题目链接:Problem - 4462
题面:
题意:一片n*n的农田,现在有k个地方的庄稼被鸟吃了,现在农夫想在这k个地方放稻草人,每个稻草人会保护曼哈顿距离为ri的农田,问最少需要几个稻草人能让剩下的庄稼不被吃,如果不行输出-1
思路:dfs,最多10个稻草人,枚举每种状态即可,被破坏了的地不用保护;
如果样例为
2
4
1 1 2 2 1 2 2 1
0 0 0 0
答案为0
保护的形状为菱形
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
int n;
int k;
int x[15], y[15];
bool s[55][55];
int z[15];
int ans = 15;
bool vis[55][55];
int cnt;
void dfs(int a, int b, int c){ //第几个稻草人,已经拿了几个稻草人,已经保护的面积大小
if(a == k){
return ;
}
dfs(a + 1, b, c); //不要这个稻草人的情况
int xx = x[a];
int yy = y[a];
vector<pair<int, int>> ve;
for(int i = 0; i <= z[a]; i++){
for(int j = 0; j <= z[a] - i; j++){
if(vis[xx][yy] == 0 && s[xx][yy] == 0){
ve.push_back({xx, yy});
vis[xx][yy] = 1;
cnt++;
}
yy++;
if(yy > n){
break;
}
}
xx++;
if(xx > n){
break;
}
yy = y[a];
}
xx = x[a];
yy = y[a];
for(int i = 0; i <= z[a]; i++){
for(int j = 0; j <= z[a] - i; j++){
if(vis[xx][yy] == 0 && s[xx][yy] == 0){
ve.push_back({xx, yy});
vis[xx][yy] = 1;
cnt++;
}
yy--;
if(yy == 0){
break;
}
}
xx++;
if(xx > n){
break;
}
yy = y[a];
}
xx = x[a];
yy = y[a];
for(int i = 0; i <= z[a]; i++){
for(int j = 0; j <= z[a] - i; j++){
if(vis[xx][yy] == 0 && s[xx][yy] == 0){
ve.push_back({xx, yy});
vis[xx][yy] = 1;
cnt++;
}
yy ++;
if(yy > n){
break;
}
}
xx--;
if(xx == 0){
break;
}
yy = y[a];
}
xx = x[a];
yy = y[a];
for(int i = 0; i <= z[a]; i++){
for(int j = 0; j <= z[a] - i; j++){
if(vis[xx][yy] == 0 && s[xx][yy] == 0){
ve.push_back({xx, yy});
vis[xx][yy] = 1;
cnt++;
}
yy --;
if(yy == 0){
break;
}
}
xx--;
if(xx == 0){
break;
}
yy = y[a];
}
if(c + ve.size() == n * n - k){
ans = min(ans, b + 1);
}else{
dfs(a + 1, b + 1, c + ve.size());
}
for(int i = 0; i < ve.size(); i++){
xx = ve[i].first;
yy = ve[i].second;
vis[xx][yy] = 0;
}
}
int main(){
ios::sync_with_stdio(false);
while(cin >> n){
if(n == 0){
break;
}
cin >> k;
memset(vis, 0, sizeof(vis));
memset(s, 0, sizeof(s));
for(int i = 0; i < k; i++){
cin >> x[i] >> y[i];
s[x[i]][y[i]] = 1;
}
for(int i = 0; i < k; i++){
cin >> z[i];
}
if(n * n - k == 0){
cout << 0 << endl;
continue;
}
ans = 15;
cnt = 0;
dfs(0, 0, 0);
if(ans == 15){
ans = -1;
}
cout << ans << endl;
}
return 0;
}