码迷,mamicode.com
首页 > 其他好文 > 详细

URAL 2029 Towers of Hanoi Strike Back 汉诺塔,从初始状态到任意给出状态需要的次数

时间:2016-07-31 01:52:02      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

F - Towers of Hanoi Strike Back
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

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.

Sample Input

input output
1
A
0
4
BBBB
15
7
BCCBABC
95

Source

UESTC 2016 Summer Training #17 Div.2

URAL 2029


My Solution

汉诺塔, 得到从初始状态到任意给出状态需要的次数的O(n)算法, 记结论吧??

比如要得到 BCCBABC

则对于原始的AAAAAAA

第一次令 res = ‘A‘, 然后对于给出的state从大的往小的开始扫, 当前是C所以第7个A变成C, ans += 2^(7 - 1), 然后res = ‘B‘, 也就是剩余的移到B上,

然后第二个需要到B上,且已经在B上, 所以不用管, 继续访问下一位

然后是A, 这个时候把当期大小的盘在B上, 所以移到A上, ans += 2^(5 - 1), 然后res = ’C‘, 剩余的全都移到第三个柱子’C‘上。

依次这样下去就好了

比较当前盘需要的在哪个柱子上和当前在那个柱子上, 如果恰好在则直接访问下一个盘子, 如果不是则把该盘移过去 ans += 2^i ( 0 <= i < n), 剩余的盘全移到第三个柱子上

把AAAAAAA.....从右往左, 全部变成state, 就可以得到答案了


此外注意点

用 1<<i得到 2^i次时,如果i很大, 比如50, 这个时候integer 溢出了, 用 (LL)(1<<50)也达不到效果, 还是得到数据丢失的integer大小的数,

然后用了cmath里的那个不大靠谱的pow, ans += (LL)pow(2, i);就可以得到 64位的整数了


复杂度 O(n)


#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int maxn = 1e2 + 8;

char val[maxn];

int main()
{
    #ifdef LOCAL
    freopen("a.txt", "r", stdin);
    //freopen("b.txt", "w", stdout);
    int T = 4;
    while(T--){
    #endif // LOCAL
    LL n, ans = 0;
    char res = 'A';
    scanf("%I64d", &n);
    scanf("%s", val);

    for(LL i = n - 1; i >= 0; i--){
        if(res != val[i]){
            ans += (LL)pow(2, i);
            //cout<<ans<<endl;
            if(res == 'A'){
                if(val[i] == 'B') res = 'C';
                else res = 'B';
            }
            else if(res == 'B'){
                if(val[i] == 'A') res = 'C';
                else res = 'A';
            }
            else if(res == 'C'){
                if(val[i] == 'A') res = 'B';
                else res = 'A';
            }
        }
        if(ans < 0 || ans > 1e18) break;
    }
    if(ans < 0 || ans > 1e18) printf("-1");
    printf("%I64d", ans);

    #ifdef LOCAL
    printf("\n");
    }
    #endif // LOCAL
    return 0;
}

  Thank you!

                                                                                                                                               ------from ProLights

URAL 2029 Towers of Hanoi Strike Back 汉诺塔,从初始状态到任意给出状态需要的次数

标签:

原文地址:http://blog.csdn.net/prolightsfxjh/article/details/52076323

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!