题解: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[提示]
本题解使用了豆包进行润色。
::::

posted @ 2026-03-12 12:59  Python_enjoy  阅读(1)  评论(0)    收藏  举报