1019 Separate the Animals (35 分)DFS或BFS搜尋+(位運算)狀態去重
阿新 • • 發佈:2018-12-23
題目連結: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; }