补周赛题也即2022年第四届河南省CCPC大学生程序设计竞赛L题
比赛题目
L.旋转水管
如图:
判断水能否成功流通出来。
我们观察这两个“零件”分别是'L'和'I',总结规律'I'的方向由上一个水管最后通过的方向决定,即如果上一个水管是最后往右走那么'I'只能通过横置也使水往右走,'L'的方向上一个水管最后通过的方向的垂直方向走,即如果上一个水管往右走那么这个'L'最后的方向只能是往上走或往下走。
由于本题的特性,走法不会太多,适合用dfs来做,选择dfs,那么怎么来调整水管最后走的方向那,只有四个走法(上,下,左,右),我们对四种方法分别打上标记,根据标记选择最后的走向,例如:我们对上下左右分别标记为1,2,3,4,那么如果上一个水管是'I'且标记是1那么这个水管就是往右上的,我们dfs也只能往上走,如果一个水管是'L'标记为1或2的话即水管最后是往上走或者往下走的那么接下来只能往左或往右走了,验证往左或往右走的可行性即可。
本题注意走过的就不能走了,也要回溯,因为要不断寻找可行路径。
AC代码如下:
#include <bits/stdc++.h>
const int N = 1e5 + 9;
bool st[3][N];
std::string s[3];
int m, ex, ey;
bool dfs(int x, int y, int u) {
if (x == 3 && y == ey)
return 1;
if (x > 2 || x < 1 || y < 0 || y > m - 1 || st[x][y])
return 0;
st[x][y] = true;
int flag;
if (s[x][y] == 'I') {
if (u == 1)
flag = dfs(x + 1, y, 1);
if (u == 2)
flag = dfs(x, y + 1, 2);
if (u == 3)
flag = dfs(x - 1, y, 3);
if (u == 4)
flag = dfs(x, y - 1, 4);
} else {
if (u == 1 || u == 3)
flag = dfs(x, y + 1, 2) || dfs(x, y - 1, 4);
else if (u == 2 || u == 4)
flag = dfs(x + 1, y, 1) || dfs(x - 1, y, 3);
}
st[x][y] = false;
return flag;
}
void solve() {
std::cin >> m >> ex >> ey;
ex--, ey--;
for (int i = 1; i <= 2; i++)
std::cin >> s[i];
std::cout << (dfs(1, ex, 1) ? "YES" : "NO") << "\n";
}
signed main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
int T;
std::cin >> T;
while (T--) {
solve();
}
return 0;
}