省选测试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
", ans);
    }
    return 0;
}

B Algebra (Unaccepted)

题目大意 :

Code

Show Code

C Anarchy (Unaccepted)

题目大意 :

Code

Show Code
原文地址:https://www.cnblogs.com/shawk/p/14425911.html