|
发表于 2003-8-20 04:38:09
|
显示全部楼层
/*采用递归编程,找到一种过河方案就返回而不是找出所有方案*/
int a[4][10];/*存放过河教程的数据,a1岸上商人b1下人过河后用a2b2表示*/
int guohe(int a1,int b1,int i,int j)
{
int m,n;
if(i>=10||(a1!=0&&a1<b1)) return (-1);
a[0]=a1;
a[1]=b1;
a[2]=0;
n=1;/*过两商人*/
if(a1>=1&&n!=j)
{
if((a1==3&&b1<2)||a1==2)
m=fanhui(a1-2,b1,i,n);
if(m==1)
{
a[2]=n;
return 1;
}
}
n=2;/*过一商一下人*/
if(a1==b1)
if(a1>0&&b1>0&&n!=j)
{
m=fanhui(a1-1,b1-1,i,n);
if(m==1)
{ a[2]=n;
return 1;
}
}
n=3;/*过两下人*/
if(b1>1&&j!=n)
{ if((a1!=3&&b1-2>=a1)||a1==3)
{ m=fanhui(a1,b1-2,i,n);
if(m==1)
{a[2]=n;
return 1;
}
}
}
return (-1) ;
}
int fanhui(int a1,int b1,int i,int j)
{
int m,n,a2,b2;
if(a1==0&&b1==0) return 1;
a2=3-a1;b2=3-b1;
a[3]=0;
n=1;/*返回两商人*/
if(a2>1&&n!=j)
{ if((a2==3&&b2<2)||a2==2)
{m=guohe(a1+2,b1,i+1,n);
if(m==1)
{a[3]=n;
return 1;}
}}
n=2;
if(a2>0&&b2>0&&n!=j)
{ m=guohe(a1+1,b1+1,i+1,n);
if(m==1){a[3]=n;return 1;}}
n=3;
if(b2>1&&j!=n)
{if((a1>1&&b1+2<=a1)||a1==0)
m=guohe(a1,b1+2,i+1,n);
if(m==1){a[3]=n;return 1;}
}n=4;/*返回一商人*/
if(a2>b2||a2==1)
{ m=guohe(a1+1,b1,i+1,n);
if(m==1){a[3]=n;return 1;}
}n=5;/*返回一下人*/
if(a1==0||a2==0)
{m=guohe(a1,b1+1,i+1,n);
if(m==1){a[3]=n;return 1;}
}}
main()
{int i,j;
clrscr();
if(guohe(3,3,1,0)!=1)printf("can't");
else
{for(i=0;i<4;i++)
{for(j=1;j<10;j++)
printf("%d ",a[j]);
printf("\n");
}}}
答案的意义
第N轮过 1 2 3 4 5 6
3 3 3 2 0 1 0 0 0 过可前岸上商人的数量
3 2 1 2 3 1 0 0 0 过河前岸上下人的数量
2 3 1 1 3 2 0 0 0 过河方案(1为同时过两商人2为过一商一下3为过两下人
4 5 2 5 4 0 0 0 0 返回方案123同上,4返回一商5返一下人
即
先过一商一仆,返回一商;过两仆人,返回一仆人;过两商人,返一商一仆;过二商,回一仆;过两仆回一商;过一商一仆。完. |
|