UVA_254
一开始看错题目了,没有按照题目的要求去做,按题目中描述的算法去做的话,在n为偶数时和我们平常移动的结果是一样的,而当n为奇数的时候,最后会把所有的盘子移到中间的柱子上,实际上就是相当于调换的中间和最后柱子而已。
在找状态的时候可以用递归来处理,我们首先指定盘子堆的初始柱子s,和该堆最下面盘子所期望移动到的柱子t,从最大的盘子找起,分情况讨论最大的盘子能否移动,然后改变相应的状态继续递归即可。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static int[] a = new int[5];
public static BigInteger[] d = new BigInteger[110];
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
int n;
BigInteger m;
d[0] = new BigInteger("1");
for(int i = 1; i <= 100; i ++)
d[i] = d[i - 1].multiply(BigInteger.valueOf(2));
while(cin.hasNext())
{
n = cin.nextInt();
m = cin.nextBigInteger();
if(n == 0)
break;
for(int i = 0; i < 3; i ++)
a[i] = 0;
dfs(0, 2, n, m);
if(n % 2 == 0)
System.out.println(a[0] + " " + a[1] + " " + a[2]);
else
System.out.println(a[0] + " " + a[2] + " " + a[1]);
}
}
public static void dfs(int s, int t, int n, BigInteger m)
{
if(n == 1)
{
if(m.equals(BigInteger.ZERO))
a[s] ++;
else
a[t] ++;
return ;
}
int k = 0;
{
int[] x = new int[3];
x[s] = 1;
x[t] = 1;
for(int i = 0; i < 3; i ++)
if(x[i] == 0)
k = i;
}
if(m.compareTo(d[n - 1]) != -1)
{
++ a[t];
m = m.add(d[n - 1].negate());
dfs(k, t, n - 1, m);
}
else
{
++ a[s];
dfs(s, k, n - 1, m);
}
}
}