CF GYM 101196 G That’s One Hanoi-ed Teacher

That’s One Hanoi-ed Teacher

链接

题意:

  询问一个汉诺塔的状态是否是最优的状态,如果是,询问还有多少步到最终状态。

分析:

  考虑汉诺塔是怎么操作的,首先是考虑F(i)是有i个盘子,从一根柱子完全移到另一根柱子的花费。如果存在x个盘子,那么答案是F(x - 1)+1+F(x-1),为前x-1盘子先从1移动到2,然后第x个盘子移动到3,然后x-1个盘子从2移到3。

  所以对于一个状态,可以先找到最大的盘子x,如果在中间的话,无解。否则使用F(x-1)+1次操作,将它移动到应该在的位置,然后当前的状态又是一样的。

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

LL ans = 0;
bool dfs(int now,vector<int>& A, vector<int> &B, vector<int> &C) {
    if (!now) return 1;
    if (A.size() && A[0] == now) {
        ans += 1ll << (now - 1);
        A.erase(A.begin());
        return dfs(now - 1, A, C, B);
    }
    if (C.size() && C[0] == now) {
        C.erase(C.begin());
        return dfs(now - 1, B, A, C);
    }
    return 0;
} 
vector<int> A, B, C;

int main() {
    int a = read();
    for (int i = 1; i <= a; ++i) A.push_back(read());
    int b = read();
    for (int i = 1; i <= b; ++i) B.push_back(read());
    int c = read();
    for (int i = 1; i <= c; ++i) C.push_back(read());
    if (!dfs(a + b + c, A, B, C)) puts("No"); 
    else printf("%I64d\n", ans);
    return 0;
}

 

posted @ 2019-02-24 15:56  MJT12044  阅读(312)  评论(0编辑  收藏  举报