题解:P15647 [ICPC 2022 Tehran R] Magic with Cards
很明显,这道题是一道 BFS。
首先做操作转化:Riffle 操作下,前 \(n\) 张的位置 \(x\) 会变为 \(2x-1\),后 \(n\) 张的位置 \(x\) 会变为 \(2 (x-n)\);Scuffle 操作下,奇数位置 \(x\) 变为 \(x+1\),偶数位置 \(x\) 变为 \(x-1\)。接着搜索:从初始位置 i 出发,把每个位置和当前步数存入队列,标记已访问的位置避免重复。每次取出队首位置,先检查是否是目标,若是则输出步数,否则按两种操作生成新位置,符合条件就入队。若队列遍历完仍未找到 \(j\),说明不可能,输出 \(- 1\)。
AC 代码如下:
#include <bits/stdc++.h>
using namespace std;
typedef pair <int, int> PII;
const int N = 2e5 + 5;
int n, s, e;
bool vis[N];
signed main() {
cin >> n >> s >> e;
queue <PII> q;
q.push({s, 0});
vis[s] = true;
while (!q.empty()) {
int x = q.front().first;
int y = q.front().second;
q.pop();
if (x == e) {
cout << y << endl;
return 0;
}
// Riffle
int tx;
if (x <= n) {
tx = 2 * x - 1;
}
else {
tx = 2 * (x - n);
}
if (!vis[tx] && (1 <= tx && tx <= 2 * n)) {
vis[tx] = true;
q.push({tx, y + 1});
}
// Scuffle
if (x % 2 == 1) {
tx = x + 1;
}
else {
tx = x - 1;
}
if (!vis[tx] && (1 <= tx && tx <= 2 * n)) {
vis[tx] = true;
q.push({tx, y + 1});
}
}
cout << -1 << endl;
return 0;
}
::::info[提示]
本题解使用了豆包进行润色。
::::

浙公网安备 33010602011771号