有个大小为n*m的二维图,.为空地,#为障碍,最外层一圈固定为障碍,起点(2,2)固定为空地,每次可以沿上下左右其中一个方向走,直到碰见障碍才能转向。问最多可以走过多少个空地?初始时方向任意,可以走多次。
bfs模拟,由于中途不能转向,把当前方向也塞到节点里。除1234分别对应上下左右外,新增一种状态5,表示遇到障碍时可以转向。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
const int Z = 205;
int dx[] = {0, 1, -1, 0, 0, 0};
int dy[] = {0, 0, 0, -1, 1, 0};
int n, m, d[Z][Z][6];
char s[Z][Z];
void solve() {
cin >> n >> m;
rep(i,1,n) rep(j,1,m) cin >> s[i][j];
queue<tuple<int,int,int>> q;
rep(i,1,5) {
q.push({2,2,i});
d[2][2][i] = 1;
}
while (!q.empty()) {
auto [x,y,z] = q.front(); q.pop();
int nx = x + dx[z];
int ny = y + dy[z];
switch (z) {
case 1:
case 2:
case 3:
case 4:
if (d[nx][ny][z] == 0) {
if (s[nx][ny] == '.') {
q.push({nx,ny,z});
d[nx][ny][z] = 1;
} else {
q.push({x,y,5});
d[x][y][5] = 1;
}
}
break;
case 5:
rep(i,1,4) if (d[x][y][i] == 0) {
q.push({x,y,i});
d[x][y][i] = 1;
}
break;
default:
break;
}
}
int ans = 0;
rep(i,1,n) rep(j,1,m) {
int ok = 0;
rep(k,1,5) if (d[i][j][k]) ok = 1;
ans += ok;
}
cout << ans << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}
标签:case,int,rep,nx,ny,push,abc311D,之不撞,南墙
From: https://www.cnblogs.com/chenfy27/p/18067121