1019 Separate the Animals (35 分)DFS或BFS搜索+(位运算)状态去重

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/usernamezzz/article/details/84455603
今日推荐