一个人要把所带的一只狗、一只鸡和一颗白菜过河,而船除人之外,每次只能带一样东西,问该如何运它们才能使鸡不吃掉白菜而狗不吃掉鸡?
提示:我们把人、鸡、狗和白菜用一个四维向量来表示,当一物在一岸时,记相应的分量为1,否则为0。如:(1,0,1,0)表示人和鸡在此岸,并称之为一个状态。按照题意(1,0,1,0)是一个允许的状态,而(0,0,1,1)是一个不允许的状态。
我们用S来记所有允许的状态:
(1,1,1,1)、(0,0,0,0)
(1,1,1,0)、(0,0,0,1)
(1,1,0,1)、(0,0,1,0)
(1,0,1,1)、(0,1,0,0)
(1,0,1,0)、(0,1,0,1)
我们把运载情况也用一个四维向量表示,例如(1,1,0,0)表示人、狗在船上而鸡不在,这样允许的状态D总共有4个:
(1,1,0,0)、(1,0,1,0)
(1,0,0,1)、(1,0,0,0)
我们规定S和D中元素相加时按二进制法则进行,一次渡河就是一个状态和另一个状态的相加
我们把(1,1,1,1)与D中的四个向量各相加,如果是允许的状态,则每一种允许的状态继续与D中的四个向量相加,直到出现(0,0,0,0)为至,如果是不允许的状态则该向量停止计算。
我写了一个算法来计算需要进行几次渡河才能顺利过去:
public class Test{
public static void main(String[] args){
int[][] state1 = {{1,1,0,0},{1,0,1,0},{1,0,0,1},{1,0,0,0}};
int[][] state2 = {{1,1,1,1},{1,1,1,0},{1,1,0,1},{1,0,1,1},{1,0,1,0},
{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,1,0,0},{0,1,0,1}};
int[][] a = new int[100][4];
int[][] b = new int[100][4];
int[] result = new int[4];
int[] correct = {0,0,0,0};
for(int i=0;i<4;i++)
a[0][i]=1;
int rows = 1;
int answer = 0;
while(true){
int rows2 = 0;
answer++;
for(int i=0;i<rows;i++){
for(int j=0;j<4;j++){
boolean input = false;
for(int k=0;k<4;k++){
result[k]=a[i][k]+state1[j][k];
if(result[k]==2)
result[k]=0;
}
for(int k=0;k<10;k++){
if(isEqual(result,state2[k])){
input= true;
break;
}
}
if(input){
for(int k=0;k<4;k++){
b[rows2][k]=result[k];
}
rows2++;
if(isEqual(result,correct))
{
System.out.println(answer);
return;
}
}
}
}
rows=rows2;
a=b;
}
}
private static boolean isEqual(int[] a,int[] b){
if(a[0]==b[0]&&a[1]==b[1]&&a[2]==b[2]&&a[3]==b[3])
return true;
else
return false;
}
}
问题是怎么出现的答题是8?应该是奇数次才对啊,怎么会是偶数次的?