0828-T3 天氣預報
題意
有 \(4\times 4\) 的村莊,有一朵 \(2 \times 2\) 的雲,需要控制雲上下左右移動,保證每個村莊都不會連續 \(7\) 天以上不下雨,也不會在不能下雨的時間下雨。問是否可以做到。
思路
搜尋。
需要注意的是打標記時只用記錄時間,雲的位置,四個角落的村莊連續未下雨的天數。
因為四個角下雨的次數不大於中間的村莊,只要四個角不幹旱,中間一定不會幹旱。
程式碼
#include <bits/stdc++.h>
using namespace std;
int n, f[400][20];
int xz[] = {1, 0, -1, 0, 0, 2, -2, 0, 0};
int yz[] = {0, 1, 0, -1, 0, 0, 0, 2, -2};
struct node {
pair<int,int> c[4];
int d[5][5], t;
};
node temp, nxt;
queue <node> q;
bool vis[366][5][5][8][8][8][8];
int trans(pair<int,int> c) {
return (c.first - 1) * 4 + c.second;
}
int main() {
while (1) {
cin >> n;
if (!n) break;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= 16; j ++)
cin >> f[i][j];
temp.c[0] = {2, 2};
temp.c[1] = {2, 3};
temp.c[2] = {3, 2};
temp.c[3] = {3, 3};
for (int i = 1; i <= 4; i ++)
for (int j = 1; j <= 4; j ++)
temp.d[i][j] = 1;
temp.d[2][2] = 0;
temp.d[2][3] = 0;
temp.d[3][2] = 0;
temp.d[3][3] = 0;
temp.t = 1;
while (!q.empty()) q.pop();
q.push(temp);
int ans = 0;
while (!q.empty()) {
temp = q.front(); q.pop();
bool ok = 1;
for (int i = 1; i <= 4; i ++)
for (int j = 1; j <= 4; j ++)
if (temp.d[i][j] >= 7) ok = 0;
for (int i = 0; i < 4; i ++)
if (f[temp.t][trans(temp.c[i])]) ok = 0;
if (!ok) continue;
if (temp.t == n) {
ans = 1;
break;
}
for (int i = 0; i < 9; i ++) {
nxt = temp; nxt.t ++;
bool OK = 1;
for (int j = 1; j <= 4; j ++)
for (int k = 1; k <= 4; k ++) nxt.d[j][k] ++;
for (int j = 0; j < 4; j ++) {
int &x = nxt.c[j].first,
&y = nxt.c[j].second;
x += xz[i], y += yz[i];
if (x < 1 || y < 1 || x > 4 || y > 4) {
OK = 0;
break;
}
nxt.d[x][y] = 0;
}
if (!OK) continue;
if (vis[nxt.t][nxt.c[0].first][nxt.c[0].second][nxt.d[1][1]][nxt.d[1][4]][nxt.d[4][1]][nxt.d[4][4]]) continue;
vis[nxt.t][nxt.c[0].first][nxt.c[0].second][nxt.d[1][1]][nxt.d[1][4]][nxt.d[4][1]][nxt.d[4][4]] = 1;
q.push(nxt);
}
}
cout << ans << "\n";
memset(vis, 0, sizeof(vis));
}
return 0;
}