省选测试26
A Alchemy
题目大意 : 经典汉诺塔,操作者一定会按最优方案移动圆盘,给出一个状态问还需多少步
-
首先一个结论,把n个圆盘从一根柱子移动到另一根柱子上的最小步数是 \(2^n-1\)
-
其实把圆盘1到i从柱s移动到柱t,简单的来说就是:
首先打开冰箱门,然后放进大象,最后关上冰箱门- 首先把圆盘1到i-1从柱s移动到柱m,然后把圆盘i从柱s移动到柱t,最后把圆盘1到i-1从柱m移动到柱t
-
如果圆盘i现在处于t,那么至少移动 \(2^{i-1}\) 步才可以到现在状态(上面圆盘1到i-1从柱s移动到柱m需要 \(2^{i-1}-1\)步,把圆盘i从柱s移动到柱t需要1步),
-
如果圆盘i现在处于s,那不用移动,如果在m的话是不可能的,输出No就好了
Code
Show Code
#include <cstdio>
using namespace std;
int read(int x = 0, int f = 1, char c = getchar()) {
for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
for (; c >='0' && c <='9'; c = getchar()) x = x * 10 + c - '0';
return x * f;
}
int n, a[55];
long long ans;
void Solve(int x, int s, int t, int m) {
if (x == 1) {
if (a[x] == t) ans--;
else if (a[x] == m) ans = -1;
return;
}
if (a[x] == s) Solve(x - 1, s, m, t);
else if (a[x] == t) ans -= 1ll << x - 1, Solve(x - 1, m, t, s);
else return ans = -1, void();
}
int main() {
for (int T = read(); T; --T) {
n = 0;
for (int i = 1; i <= 3; ++i)
for (int k = read(); k; --k)
a[read()] = i, ++n;
ans = (1ll << n) - 1;
Solve(n, 1, 3, 2);
if (ans < 0) puts("No");
else printf("%lld\n", ans);
}
return 0;
}
B Algebra (Unaccepted)
题目大意 :
Code
Show Code
C Anarchy (Unaccepted)
题目大意 :
Code
Show Code