汉诺塔问题
给定一个整数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));
}
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号