Towers of Hanoi Strike Back URAL - 2029

The Tower of Hanoi puzzle was invented by French mathematician Édouard Lucas in the second half of the 19th century. Here is its formulation.

There are three rods, denoted by the letters A, B, and C, and n disks of different integer sizes from 1 to  n. Initially the disks are stacked in ascending order of size on rod A, the smallest at the top, thus making a conical shape. Each move consists of taking the upper disk from one of the rods and placing it on top of the stack at another rod, with the following condition satisfied: no disk may be placed on top of a smaller disk. The objective of the puzzle is to move the entire stack to rod B in the smallest possible number of moves. The auxiliary rod C can be used in the process.

The state of the rods at each time can be described by a string of n letters A, B, and C: the letter at position i denotes the rod where the disk of size  i is at that time. For example, the initial state is given by the string containing letters A only, and the final state is described by the string consisting of letters B. The converse is also true: any such string uniquely describes a valid state of the rods, because the order of disks on a rod is uniquely defined by their size.

Imagine that you are required to pass from the initial state, where all the disks are on rod A, to some prescribed state. What is the smallest number of moves in which this can be done?

Input

The first line contains an integer n (1 ≤ n ≤ 50).

In the second line you are given n uppercase English letters A, B, C, which describe the final state.

Output

If it is impossible to obtain the final state from the initial state, output “-1” (without quotation marks). Otherwise, output the minimum number of moves. It is guaranteed that, if there is an answer, it does not exceed 10 18.

Example

inputoutput
1
A
0
4
BBBB
15
7
BCCBABC
95
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;
ll a[55];
char s[100];
int main()
{
    ll n, i;
    a[0] = 0; a[1] = 1;
    for(i = 2; i <= 50; i ++)   // 汉诺塔公式
    {
        a[i] = a[i - 1] * 2 + 1;
    }
    scanf("%lld",&n);
    scanf("%s",s+1);
    ll x = 1;  // 来表示一开始在的位置
    ll ans = 0;
    for(i = n; i >= 1; i--)   // 如果想要由位置1移到位置3,那么2为跳板,位置x更新为跳板
    {
        if(x==1&&s[i]=='A') continue;
        else if(x==1&&s[i]=='B'){ans+=a[i-1]+1;x=3;}
        else if(x==1&&s[i]=='C'){ans+=a[i-1]+1;x=2;}
        else if(x==2&&s[i]=='A') {ans+=a[i-1]+1;x=3;}
        else if(x==2&&s[i]=='B')continue;
        else if(x==2&&s[i]=='C'){ans+=a[i-1]+1;x=1;}
        else if(x==3&&s[i]=='A'){ans+=a[i-1]+1;x=2;}
        else if(x==3&&s[i]=='B'){ans+=a[i-1]+1;x=1;}
        else if(x==3&&s[i]=='C') continue;
    }
    printf("%lld\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值