题目链接:https://pintia.cn/problem-sets/994805148990160896/problems/994805149963239424
直接暴力搜索每一种障碍的状态,用dfs和bfs都可以(我用的dfs),没找到一种状态bfs检查现在有多少个洞,有没有动物相连。
可以用set对状态进行去重,用 long long 压缩保存状态
写题一定要细心。。。。。。。。。。
code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<map>
using namespace std;
#define N 7
#define ll long long
int n, m, k, h;
int result = 0;
string mp[N];
set<ll>q;
ll yi = 1;
int vis[N][N], point[N][N];
int dir[4][2] = { 0,1,1,0,0,-1,-1,0 };
bool check(ll now) {
//cout<<"Start"<<endl;
bool hole = true;
int HOLE = 0;
int f[N][N];
ll cmt = now;
int ans = 0, ani = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
f[i][j] = point[i][j];
}
}
while (cmt) {
if (cmt & 1) {
int x = ans / m + 1;
int y = ans % m + 1;
//cout << x << " " << y << endl;
f[x][y] = 2;
}
ans++;
cmt >>= 1;
}
queue<pair<int, int>>Q;
for(int i=1;i<=n;i++)
for (int j = 1; j <= m; j++) {
if (f[i][j] == 2)continue;
ani = (f[i][j] == 1);
f[i][j] = 2;
Q.push(make_pair(i, j));
while (!Q.empty()) {
int x = Q.front().first;
int y = Q.front().second;
Q.pop();
for (int j = 0; j < 4; j++) {
int xx = x + dir[j][0], yy = y + dir[j][1];
if (xx <= 0 || xx > n || yy <= 0 || yy > m) {
hole = false;
continue;
}
if (f[xx][yy] == 2) continue;
if (f[xx][yy] == 1)ani++;
if (ani >= 2)return false;
Q.push(make_pair(xx, yy));
f[xx][yy] = 2;
}
}
if (hole)HOLE++;
hole = true;
}
if (HOLE == h) {
//cout << "YRS" << endl;
return true;
}
return false;
}
void dfs(ll now, int t) {
//printf("%#x\n", now);
if (q.count(now))
return;
q.insert(now);
if (t == k) {
if (check(now))
result++;
return;
}
ll ts = now;
int tmp = 0;
while (ts) {
if (ts & 1) {
int u = (tmp / m) + 1, v = (tmp%m) + 1;
for (int i = 0; i < 4; i++) {
int x = u + dir[i][0], y = v + dir[i][1];
//cout << x << " " << y <<" "<<point[x][y]<<" "<<vis[x][y]<< endl;
if (point[x][y] == 0 && x <= n && x > 0 && y <= m && y > 0 && vis[x][y] == 0) {
vis[x][y] = 1;
//cout << x << " " << y << endl;
dfs( now | (1LL << ((x - 1)*m) + (y - 1)), t + 1);
vis[x][y] = 0;
}
}
}
tmp++;
ts >>= 1;
}
}
int main() {
cin >> n >> m >> k >> h;
cin.get();
for (int i = 1; i <= n; i++) {
cin >> mp[i];
for (int j = 1; j <= m; j++) {
point[i][j] = mp[i][j-1] == '.' ? 0 : 1;
}
cin.get();
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (!point[i][j]) {
memset(vis, 0, sizeof(vis));
vis[i][j] = 1;
dfs(1LL << ((i - 1)*m + j - 1), 1);
}
}
}
cout << result << endl;
return 0;
}