2025.04.25 作业 - Trapped in the Witch's Labyrinth
https://codeforces.com/problemset/problem/2034/C
题目描述:Trapped in the Witch's Labyrinth
在波斯史诗《列王纪》中,传说中的英雄罗斯坦姆的第四项劳动中,一个老女巫创建了一个魔法迷宫来困住他。迷宫是一个由 n 行和 m 列组成的矩形网格。每个格子都指向一个特定的方向:上、下、左或右。女巫对罗斯坦姆施了魔法,使得每当他站在一个格子时,他都会按照该格子指示的方向移动到相邻的格子。
如果罗斯坦姆最终离开迷宫(即移动到一个不存在的格子),他将摆脱女巫的魔法并打败她。然而,如果他永远被困在迷宫内(即在内部循环),他将永远无法逃脱。
女巫尚未确定所有格子的方向。她希望以最大化罗斯坦姆将永远被困的起点数量的方式,为未指定的格子分配方向。你的任务是找出这个最大的被困起点数量。
输入格式
第一行包含一个整数 t(1 ≤ t ≤ 10^4),表示测试用例的数量。
对于每个测试用例:
- 第一行包含两个整数
n和m(1 ≤ n, m ≤ 1000),表示迷宫的行数和列数。 - 接下来的
n行,每行包含一个长度为m的字符串,表示迷宫中的方向。每个字符是以下之一:U(上)D(下)L(左)R(右)?(未指定的方向)
数据保证:所有测试用例的 n ⋅ m 之和不超过 10^6。
输出格式
对于每个测试用例,输出一个整数,表示在最优分配 ? 格子的方向后,罗斯坦姆会永远被困的起点的最大可能数量。
样例
输入
3
3 3
UUU
L?R
DDD
2 3
???
???
3 3
?U?
R?L
RDL
输出
0
6
5
算法解析
- 思考1:
URDL,一定不被困住的格子等价于走到一个不被困住的格子。比被困住更容易判定。 - 思考2: 任何一个格子是不被困住的,都需要从最外圈的格子逃离。
- 思考3: 最外圈的格子,可以直接判定不会被困住,可以逆向找出哪些格子会走到被困住的格子。
- 思考4:
?,希望这些格子被困住。当四周都是 不被困住的格子时,就一定不被困住。 - 思考5: 剩余的格子都是被困住的。
#include <bits/stdc++.h>
using namespace std;
int D[1004][1004],s[1004][1004];
const int dx[4]={-1,0,1,0};
const int dy[4]={0,1,0,-1};
int dir_Mp[256];
queue<pair<int,int>> Q;
bool Flg[1004][1004];
int main() {
int T;
cin>>T;
dir_Mp['U']=0;dir_Mp['R']=1;dir_Mp['D']=2;dir_Mp['L']=3;
while (T--) {
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) {
char ch;
scanf(" %c",&ch);
if (ch=='?') D[i][j]=-1;else D[i][j]=dir_Mp[ch];
}
Q=queue<pair<int, int>>(); //队列清空;
memset(Flg,0,sizeof(Flg));
memset(s,0,sizeof(s));
int Ans=0;
for (int i=1;i<=m;i++) {
s[0][i]=s[n+1][i]=1;
if (D[1][i]==0)
Ans++,s[1][i]=1,Q.push({1,i}),Flg[1][i]=1;
if (D[n][i]==2)
Ans++,s[n][i]=1,Q.push({n,i}),Flg[n][i]=1;
}
for (int i=1;i<=n;i++) {
s[i][0]=s[i][m+1]=1;
if (D[i][1]==3)
Ans++,s[i][1]=1,Q.push({i,1}),Flg[i][1]=1;
if (D[i][m]==1)
Ans++,s[i][m]=1,Q.push({i,m}),Flg[i][m]=1;
}
while (!Q.empty()) {
pair T=Q.front(); Q.pop();
int x,y,Tx,Ty;
x=T.first;y=T.second;
for (int i=0;i<4;i++) {
Tx=x+dx[i];Ty=y+dy[i];
//cout<<Tx<<" "<<Ty<<" "<<i<<endl;
if (Tx<1||Tx>n||Ty<1||Ty>m||Flg[Tx][Ty]) continue;
if (D[Tx][Ty]==-1) continue;
if ((D[Tx][Ty]+2)%4==i) {
Ans++; //cout<<Tx<<" "<<Ty<<endl;
s[Tx][Ty]=1;Flg[Tx][Ty]=1;Q.push({Tx,Ty});
}
}
}
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++) {
if (D[i][j]==-1) {
bool F=1;
for (int k=0;k<4;k++) {
int Tx,Ty;
Tx=i+dx[k];Ty=j+dy[k];
if (s[Tx][Ty]!=1) F=0;
}
if (F) Ans++;
}
}
cout<<n*m-Ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号