汉诺塔问题

链接

给定一个整数n,代表汉诺塔游戏中从小到大放置n个圆盘,假设开始所有圆盘都在左边的柱子上,那么用最优的办法把所有圆盘都移动到右边的柱子上的过程,就称为最优移动轨迹。给定一个整型数组arr, 其中只含有1、2和3,代表所有圆盘目前的状态,1代表左柱,2代表中柱,3代表右柱,a[i]的值代表第i+1个圆盘的位置(a[i]下标从0开始)。比如,arr=[3,3,2,1], 代表第1个圆盘在右柱上、第2个圆盘在右柱上、第3个圆盘在中柱上、第4个圆盘在左柱上。如果arr代表的状态是最优移动轨迹过程中出现的状态,输出arr这种状态是最优移动轨迹中的第几个状态。如果arr代表的状态不是最优移动轨迹过程中出现的状态,则输出-1。

import java.util.Scanner;

public class Main {

    private static final int MOD = 1000000007;

    private static long pow(int x, int n) {
        long ret = 1;
        long base = x;
        while (n != 0) {
            if ((n & 1) == 1) {
                ret = (ret * base) % MOD;
            }
            n >>= 1;
            base = (base * base) % MOD;
        }
        return ret % MOD;
    }

    private static int solve(int[] arr, int from, int to, int other, int num) {
        if (num == 0) {
            return 0;
        }
        if (arr[num - 1] == other) {
            return -1;
        }

        if (arr[num - 1] == from) {
            return solve(arr, from, other, to, num - 1);
        } else {
            int rest = solve(arr, other, to, from, num - 1);
            if (rest == -1) {
                return -1;
            }
            return rest + (1 << (num - 1));
        }
    }

    private static long dp(int[] arr) {
        int num = arr.length;
        int from = 1, to = 3, other = 2;
        long ret = 0;
        while (num > 0) {
            if (arr[num - 1] == other) {
                return -1;
            }
            if (arr[num - 1] == from) {
                to = to ^ other;
                other = to ^ other;
                to = to ^ other;
            } else {
                ret = (ret + pow(2, num - 1)) % MOD;
                other = other ^ from;
                from = other ^ from;
                other = other ^ from;
            }
            num--;
        }
        return ret;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        while (in.hasNext()) {
            int n = in.nextInt();
            int[] arr = new int[n];

            for (int i = 0; i < n; ++i) {
                arr[i] = in.nextInt();
            }
            System.out.println(dp(arr));
        }

    }
}
posted @ 2021-10-19 18:08  Tianyiya  阅读(70)  评论(0)    收藏  举报