c语言传教士与野人过河程序

我设计的三个野人ic三个传教士im,船上能在两个人,乘船左岸到右岸用boatf,右岸到左岸用boatr,具体程序如下,但是好像出现了死循环,却看不出那里出了问题,请各位高手帮个忙看一看,谢谢啦!
#include<stdio.h>
int im,ic,ii,ij;
int boatf(int im,int ic,int ii)
{
switch(ii)
{
case 1:printf("M:%d C:%d\n",im--,ic--);break;
case 2:printf("M:%d C:%d\n",im=im-2,ic);break;
case 3:printf("M:%d C:%d\n",im,ic=ic-2);break;
case 4:printf("M:%d C:%d\n",im--,ic);break;
case 5:printf("M:%d C:%d\n",im,ic--);break;
default:printf("error\n");
}

}
int boatr(int im,int ic,int ij)
{
switch(ij)
{
case 1: printf("M:%d C:%d\n",im++,ic++);break;
case 2:printf("M:%d C:%d\n",im=im+2,ic);break;
case 3:printf("M:%d C:%d\n",im,ic=ic+2);break;
case 4:printf("M:%d C:%d\n",im++,ic);break;
case 5:printf("M:%d C:%d\n",im,ic++);break;
default:printf("error\n");
}
}
void main()
{
im=3;
ic=3;
lflag:
for(ii=1;ii<=5;ii++)
{
boatf(im,ic,ii);
if(im<ic||im<0||ic<0)
{
printf("the %dth plan to R is fail!\n",ii);
}
else if(im==0&&ic==0)
{
printf("the plan to Pass the river is complete!\n");
break;
}

else
{
for(ij=1;ij<=5;ij++)
boatr(im,ic,ij);
if(im<ic||im<0||ic<0)
{
printf("the %dth plan to F is fail!\n",ij);
}
else
goto lflag;
}

}
}

你把问题看简单了。你的程序有几个问题: 

int boatf(int im,int ic,int ii)在这个函数中改变的im和ic的值只是改变的两个临时变量的值,并没有改变全局变量im和ic的值。你可以把前两个参数去掉。 

还有,你的for循环并不是可以正确遍历所有情况的。 

我写了一个程序,tc2.0通过了。在执行到第145种方案时成功。 

程序中case的几个顺序请不要任意改动,因为ltor和rtol函数中他们有对应关系。

本题目一共有5的13次方种方案,我的算法能排除很多非法方案。当然,我的算法不是最好的,希望高手能提供更高效的算法。 

做这个程序累坏了我几万个脑细胞,楼主给多加点分吧!谢谢了! 

#include<stdio.h>
/*定义N为所用步数,先定为6步*/
#define N 6
/*分别为左岸和右岸的im,ic数*/
int iml, imr, icl, icr;
/*定义sn为左右岸的移动的每一步*/
int sn[N+N-1] = {0};
void ltor(int i)
/* left to right */
{
    switch (i) {
    case 0:
        iml--;
        icl--;
        printf("%dim %dic | im + ic --> | %dim %dic\n", iml, icl, imr, icr);
        imr++;
        icr++;
        break;
    case 1:
        iml -= 2;
        printf("%dim %dic | im + im --> | %dim %dic\n", iml, icl, imr, icr);
        imr += 2;
        break;
    case 2:
        icl -= 2;
        printf("%dim %dic | ic + ic --> | %dim %dic\n", iml, icl, imr, icr);
        icr += 2;
        break;
    case 3:
        iml--;
        printf("%dim %dic |    im   --> | %dim %dic\n", iml, icl, imr, icr);
        imr++;
        break;
    case 4:
        icl--;
        printf("%dim %dic |    ic   --> | %dim %dic\n", iml, icl, imr, icr);
        icr++;
        break;
    default:
        printf("error\n");
    }
}
void rtol(int i)
/* right to left */
{
    switch (i) {
    case 0:
        imr--;
        icr--;
        printf("%dim %dic | <-- im + ic | %dim %dic\n", iml, icl, imr, icr);
        iml++;
        icl++;
        break;
    case 1:
        imr -= 2;
        printf("%dim %dic | <-- im + im | %dim %dic\n", iml, icl, imr, icr);
        iml += 2;
        break;
    case 2:
        icr -= 2;
        printf("%dim %dic | <-- ic + ic | %dim %dic\n", iml, icl, imr, icr);
        icl += 2;
        break;
    case 3:
        imr--;
        printf("%dim %dic | <--    im   | %dim %dic\n", iml, icl, imr, icr);
        iml++;
        break;
    case 4:
        icr--;
        printf("%dim %dic | <--    ic   | %dim %dic\n", iml, icl, imr, icr);
        icl++;
        break;
    default:
        printf("error\n");
    }
}
int set(int k)
/* set sn[i] */
{
    int i;
    for (i = k + 1; i < N + N - 1; i++)
    /* k 位之后的sn元素都赋值为零*/
    sn[i] = 0;
    sn[k]++;
    /* k 位元素自加1*/
    for (i = k; i > 0; i--)
    /* 每位元素超过4则置零,并向前一位进一*/
    {
        if (sn[i] > 4) {
            sn[i] = 0;
            sn[i - 1]++;
        } else break;
    }
    if (sn[0] > 5)
    /*sn遍历一遍则返回0,否则返回1*/
    return 0;
    else return 1;
}
void restart(void)
/* restart the work */
{
    imr = icr = 0;
    iml = icl = 3;
}
void main() {
    int i,
    step,
    found = 0;
    unsigned long n = 0;
    /* The NUM of the plans */
    do {
        i = 0;
        step = N - 1;
        n++;
        restart();
        ltor(sn[i]);
        while ((step--) || !(iml == 0 && icl == 0)) {
            i++;
            rtol(sn[i]);
            if (sn[i] == sn[i - 1]) {
                printf("The %ldth plan to R is not perfect!\n", n);
                break;
            }
            if ((imr > 0 && imr < icr) || imr < 0 || icr < 0 || (iml > 0 && iml < icl) || iml < 0 || icl < 0) {
                printf("The %ldth plan to R is fail!\n", n);
                break;
            }
            i++;
            ltor(sn[i]);
            if (sn[i] == sn[i - 1]) {
                printf("The %ldth plan to R is not perfect!\n", n);
                break;
            }
            if ((imr > 0 && imr < icr) || imr < 0 || icr < 0 || (iml > 0 && iml < icl) || iml < 0 || icl < 0) {
                printf("The %ldth plan to R is fail!\n", n);
                break;
            }
        }
        if (iml == 0 && icl == 0) {
            printf("The plan to Pass the river is success!\n");
            getchar();
            break;
        }
    } while ( set ( i ));
}

温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-03-29
你把问题看简单了。你的程序有几个问题:
int
boatf(int
im,int
ic,int
ii)在这个函数中改变的im和ic的值只是改变的两个临时变量的值,并没有改变全局变量im和ic的值。你可以把前两个参数去掉。
还有,你的for循环并不是可以正确遍历所有情况的。
我写了一个程序,tc2.0通过了。在执行到第145种方案时成功。
程序中case的几个顺序请不要任意改动,因为ltor和rtol函数中他们有对应关系。
本题目一共有5的13次方种方案,我的算法能排除很多非法方案。当然,我的算法不是最好的,希望高手能提供更高效的算法。
做这个程序累坏了我几万个脑细胞,楼主给多加点分吧!谢谢了!
#include<stdio.h>
#define
N
6
/*定义N为所用步数,先定为6步*/
int
iml,imr,icl,icr;
/*分别为左岸和右岸的im,ic数*/
int
sn[N+N-1]={0};
/*定义sn为左右岸的移动的每一步*/
void
ltor(int
i)
/*
left
to
right
*/
{
switch(i)
{
case
0:
iml--;icl--;
printf("%dim
%dic
|
im
+
ic
-->
|
%dim
%dic\n",iml,icl,imr,icr);
imr++;icr++;
break;
case
1:
iml-=2;
printf("%dim
%dic
|
im
+
im
-->
|
%dim
%dic\n",iml,icl,imr,icr);
imr+=2;
break;
case
2:
icl-=2;
printf("%dim
%dic
|
ic
+
ic
-->
|
%dim
%dic\n",iml,icl,imr,icr);
icr+=2;
break;
case
3:
iml--;
printf("%dim
%dic
|
im
-->
|
%dim
%dic\n",iml,icl,imr,icr);
imr++;
break;
case
4:
icl--;
printf("%dim
%dic
|
ic
-->
|
%dim
%dic\n",iml,icl,imr,icr);
icr++;
break;
default:printf("error\n");
}
}
void
rtol(int
i)
/*
right
to
left
*/
{
switch(i)
{
case
0:
imr--;icr--;
printf("%dim
%dic
|
<--
im
+
ic
|
%dim
%dic\n",iml,icl,imr,icr);
iml++;icl++;
break;
case
1:
imr-=2;
printf("%dim
%dic
|
<--
im
+
im
|
%dim
%dic\n",iml,icl,imr,icr);
iml+=2;
break;
case
2:
icr-=2;
printf("%dim
%dic
|
<--
ic
+
ic
|
%dim
%dic\n",iml,icl,imr,icr);
icl+=2;
break;
case
3:
imr--;
printf("%dim
%dic
|
<--
im
|
%dim
%dic\n",iml,icl,imr,icr);
iml++;
break;
case
4:
icr--;
printf("%dim
%dic
|
<--
ic
|
%dim
%dic\n",iml,icl,imr,icr);
icl++;
break;
default:printf("error\n");
}
}
int
set(int
k)
/*
set
sn[i]
*/
{
int
i;
for(i=k+1;i<N+N-1;i++)
/*
k
位之后的sn元素都赋值为零*/
sn[i]=0;
sn[k]++;
/*
k
位元素自加1*/
for(i=k;i>0;i--)
/*
每位元素超过4则置零,并向前一位进一*/
{
if(sn[i]>4)
{
sn[i]=0;
sn[i-1]++;
}
else
break;
}
if(sn[0]>5)
/*sn遍历一遍则返回0,否则返回1*/
return
0;
else
return
1;
}
void
restart(void)
/*
restart
the
work
*/
{
imr=icr=0;
iml=icl=3;
}
void
main()
{
int
i,step,found=0;
unsigned
long
n=0;
/*
The
NUM
of
the
plans
*/
do
{
i=0;
step=N-1;
n++;
restart();
ltor(sn[i]);
while((step--)
||
!(iml==0
&&
icl==0))
{
i++;
rtol(sn[i]);
if(sn[i]==sn[i-1])
{
printf("The
%ldth
plan
to
R
is
not
perfect!\n",n);
break;
}
if((imr>0
&&
imr<icr)
||
imr<0
||
icr<0
||
(iml>0
&&
iml<icl)
||
iml<0
||
icl<0)
{
printf("The
%ldth
plan
to
R
is
fail!\n",n);
break;
}
i++;
ltor(sn[i]);
if(sn[i]==sn[i-1])
{
printf("The
%ldth
plan
to
R
is
not
perfect!\n",n);
break;
}
if((imr>0
&&
imr<icr)
||
imr<0
||
icr<0
||
(iml>0
&&
iml<icl)
||
iml<0
||
icl<0)
{
printf("The
%ldth
plan
to
R
is
fail!\n",n);
break;
}
}
if(iml==0
&&
icl==0)
{
printf("The
plan
to
Pass
the
river
is
success!\n");
getchar();
break;
}
}while(set(i));
}
第2个回答  2008-11-17
程序很乱阿,没细看

你那 for(ii=1;ii<=5;ii++)
ii 永远都是1,还没执行 ii++ 就 goto了

建议不要用goto
相似回答