关于狗、鸡、白菜过河的算法
2005-04-11 22:48
288 查看
一个人要把所带的一只狗、一只鸡和一颗白菜过河,而船除人之外,每次只能带一样东西,问该如何运它们才能使鸡不吃掉白菜而狗不吃掉鸡?
提示:我们把人、鸡、狗和白菜用一个四维向量来表示,当一物在一岸时,记相应的分量为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?应该是奇数次才对啊,怎么会是偶数次的?
提示:我们把人、鸡、狗和白菜用一个四维向量来表示,当一物在一岸时,记相应的分量为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?应该是奇数次才对啊,怎么会是偶数次的?
相关文章推荐
- 人狼羊白菜过河问题算法,C++代码实现
- 关于连连看随机排列的算法
- 关于全局ID,雪花(snowflake)算法的说明
- 一道关于排序的算法题
- 关于用java io实现文件压缩与解压(不涉及压缩算法)
- 关于算法
- 一个关于移位的问题的多种算法求解
- 关于算法,那些你不知道的事
- 关于FP-Growth 算法一个很好的ppt-学习分享
- 关于大学生算法竞赛
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- 关于模糊控制算法
- 关于图像相似度算法的文章
- 关于内表数据汇总的一些算法
- JAVA关于GC的全部算法
- 【摄影】关于景深的概念和算法!!!(转)
- 几篇关于无限分类算法的文章第1/5页
- 关于树的一些算法
- 关于一些图论的算法