❶ c语言一个人带着一只羊,一颗白菜,一条狼想过河,假设他每次只能带一只羊,一只狼或一颗白菜过河,并限
这个题目是不是哪里出了问题?
按照这个要求,不论先带哪个过河都不行啊,剩下的两个总是不能单独在一起的啊。。。
❷ 数学建模 人狼羊菜问题
1。先送羊,回,再送狼,带回羊,送菜,回,再送一次羊!
2。先送羊,回,再送菜,带回羊,送狼,回,再送一次羊!
❸ C语言编程!!!羊,狼,白菜,过河方法~!~~@。@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STEP 20
//index: 0 - 狼,1-羊,2-菜,3-农夫,value:0-本岸,1-对岸
int a[MAX_STEP][4];
int b[MAX_STEP];
char *name[] =
{
"空手",
"带狼",
"带羊",
"带菜"
};
void search(int iStep)
{
int i;
if (a[iStep][0] + a[iStep][1] + a[iStep][2] + a[iStep][3] == 4)
{
for (i = 0; i < iStep; i++)
{
if (a[i][3] == 0)
{
printf("%s到对岸\n", name[b[i] + 1]);
}
else
{
printf("%s回本岸\n", name[b[i] + 1]);
}
}
printf("\n");
return;
}
for (i = 0; i < iStep; i++)
{
if (memcmp(a[i], a[iStep], sizeof(a[i])) == 0)
{
return;
}
}
if (a[iStep][1] != a[iStep][3] && (a[iStep][2] == a[iStep][1] || a[iStep][0] == a[iStep][1]))
{
return;
}
for (i = -1; i <= 2; i++)
{
b[iStep] = i;
memcpy(a[iStep + 1], a[iStep], sizeof(a[iStep + 1]));
a[iStep + 1][3] = 1 - a[iStep + 1][3];
if (i == -1)
{
search(iStep + 1);
}
else if (a[iStep][i] == a[iStep][3])
{
a[iStep + 1][i] = a[iStep + 1][3];
search(iStep + 1);
}
}
}
int main()
{
search(0);
return 0;
}
❹ 人 狼 羊 菜 过河 perl
#include <iostream>
using namespace std;
const int VEGET = 1;
const int SHEEP = VEGET << 1;
const int WOLF = SHEEP << 1;
const int FARMER = WOLF << 1;
bool used[20]; // 状态是否到达过的标志
int bfs[1000]; // 广度优先搜索时存放状态
int pre[1000]; // 父结点
inline int SetBit( int x, int pos )
{
return x | pos;
}
inline int DelBit( int x, int pos )
{
return x & ~pos;
}
// 检查状态x是否合法
inline bool IsLegal( int x )
{
if ( x & FARMER ) // 如果农夫在的话
{
// 菜和羊都不在,或是羊和狼都不在是不可以的
if ( ((x&(VEGET|SHEEP))==0) || ((x&(SHEEP|WOLF))==0) )
{
return false;
}
} else // 如果农夫不在的话
{
// 菜和羊都在,或是羊和狼都在是不可以的
if ( ((x&(VEGET|SHEEP))==(VEGET|SHEEP)) || ((x&(SHEEP|WOLF))==(SHEEP|WOLF)) )
{
return false;
}
}
// 否则,是合法的状态
return true;
}
// 广度优先搜索
int BFSSearch()
{
int i;
int x;
int iLeft = -1;
int iRight = 1;
bfs[0] = FARMER|WOLF|SHEEP|VEGET;
used[ bfs[0] ] = true;
while( ++iLeft<iRight ) // 只要状态没有结束
{
if ( bfs[iLeft] & FARMER ) // 这里有农夫
{
x = DelBit(bfs[iLeft],FARMER);
if ( !used[x] && IsLegal(x) ) // 农夫什么都不带过去
{
pre[iRight] = iLeft;
bfs[iRight] = x;
used[x] = true;
iRight++;
}
for ( i=0; i<3; i++ ) // 带一样东西过去
{
if ( (bfs[iLeft]&(1<<i)) == 0 ) // 如果要带过去的不在这边
{
continue;
}
x = DelBit(bfs[iLeft],FARMER|(1<<i) );
if ( !used[x] && IsLegal(x) ) // 状态不存在且可行
{
pre[iRight] = iLeft;
bfs[iRight] = x;
used[x] = true;
if( x == 0 ) // 如果找到目标,返回
{
return iRight;
}
iRight++;
}
}
} else
{
x = SetBit(bfs[iLeft],FARMER);
if ( !used[x] && IsLegal(x) ) // 农夫什么都不带回来
{
pre[iRight] = iLeft;
bfs[iRight] = x;
used[x] = true;
iRight++;
}
for ( i=0; i<3; i++ ) // 带一样东西回来
{
if ( bfs[iLeft]&(1<<i) ) // 如果要带回来的已经在这边
{
continue;
}
x = SetBit(bfs[iLeft],FARMER|(1<<i) );
if ( !used[x] && IsLegal(x) ) // 状态不存在且可行
{
pre[iRight] = iLeft;
bfs[iRight] = x;
used[x] = true;
if( x == 0 )
{
return iRight;
}
iRight++;
}
}
}
}
return -1;
}
// 递归输出结果
void OutputSolution( int iRet )
{
if ( pre[iRet] != -1 )
{
OutputSolution( pre[iRet] );
}
cout << " --> ";
if ( bfs[iRet]&FARMER )
{
cout << "Farmer ";
} else
{
cout << " ";
}
if ( bfs[iRet]&WOLF )
{
cout << "Wolf ";
} else
{
cout << " ";
}
if ( bfs[iRet]&SHEEP )
{
cout << "Sheep ";
} else
{
cout << " ";
}
if ( bfs[iRet]&VEGET )
{
cout << "Vegetable ";
} else
{
cout << " ";
}
cout << endl;
}
int main(int argc, char* argv[])
{
memset( used, 0, sizeof(used) );
memset( pre, 0xff, sizeof(pre) );
int iRet = BFSSearch();
if ( iRet == -1 )
{
cout << "No solution!" << endl;
} else
{
OutputSolution( iRet );
}
return 0;
}
❺ 求狼羊白菜过河的C语言编程题详解。希望不要用数组解决。
按照你的要求,不使用数组。
我的思路,起点货物狼、羊、白菜,人一直在开船,通过递归函数,每次靠岸尝试装卸货方案,直到找满足条件的方案。将可行方案存放在结构链表中形成操作流水打印。
人狼羊菜存储方式模拟4位2进制,用1111表示,每位表示一个单位,1存在,0不存在。
#include<stdio.h>
#include<malloc.h>
typedefenum{false,true}bool;
typedefstructopRecord//用结构链表记录操作流水
{
intp1_take;//p1载货值
intp1_goAd;//p1卸货值
intp2_take;//p2载货值
intp2_goAd;//p2卸货值
intcen;//递归层号
structopRecord*next;
}OPR;
OPR*oprHead;
OPR*oprTail;
char*getName(intb);//获取对应名称
intbeEaten(intp1,intp2);//检查是否发生被吃事件,发生返回1,未发生返回0
inttoShip(int*p1,int*p2,int*ship,boolf);//递归函数:上船人及任意一组合,返回状态,1:方案可行;0:方案不可行
intgetFist(intpn);//获取物品组合中第一个
voidaddLog(intp1_take,intp1_goAd,intp2_take,intp2_goAd,intcen);//将有效操作添加进日志,cen相同,将视为修改覆盖
voidprintfLog();//打印操作流水
OPR*findLogBycen(intcen);//通过cen查找流水。有返回节点指针。无返回NULL
intcount=1;
intflag=0;//标识变量=1成立;=0不成立
intcen=0;
intmain()
{
intp1=111,ship=1000,p2=0000;//p1,p2分别表示两岸,4位数每一位分别表示人狼羊菜,位数值1表示存在,0表示不存在
oprHead=(OPR*)malloc(sizeof(OPR));
oprHead->next=NULL;
oprTail=NULL;
printf("河岸有人、狼、羊、白菜要过河,船每次载人及一物,为避免人上船后狼吃羊或羊吃菜
开始生成方案:
");
if(toShip(&p1,&p2,&ship,0))
{
printf("
开始生成结果报告:
");
printfLog();
}
else
printf("无可行方案!!
");
return0;
}
voidaddLog(intp1_take,intp1_goAd,intp2_take,intp2_goAd,intcen)//将有效操作添加进日志,cen相同,将视为修改覆盖,
{
OPR*oprNew=findLogBycen(cen);
if(oprNew==NULL)//通过查找。确认无记录,新增记录
{
oprNew=(OPR*)malloc(sizeof(OPR));
oprNew->p1_take=p1_take;
oprNew->p1_goAd=p1_goAd;
oprNew->p2_take=p2_take;
oprNew->p2_goAd=p2_goAd;
oprNew->cen=cen;
oprNew->next=NULL;
if(oprHead->next==NULL)
oprHead->next=oprNew;
else
oprTail->next=oprNew;
oprTail=oprNew;
}
else//查找发现已有记录,修改
{
oprNew->p1_take=p1_take;
oprNew->p1_goAd=p1_goAd;
oprNew->p2_take=p2_take;
oprNew->p2_goAd=p2_goAd;
}
}
OPR*findLogBycen(intcen)//通过cen查找流水。有返回节点指针。无返回NULL
{
OPR*headSave=oprHead;
while(headSave->next!=NULL)
{
if(headSave->next->cen==cen)
returnheadSave->next;
headSave=headSave->next;
}
returnNULL;
}
voidprintfLog()//打印操作流水
{
OPR*headSave=oprHead;
intp1_take,p1_goAd,p2_take,p2_goAd,cen,p1TOp2,p2TOp1;
while(headSave->next!=NULL)
{
p1_take=headSave->next->p1_take;
p1_goAd=headSave->next->p1_goAd;
p2_take=headSave->next->p2_take;
p2_goAd=headSave->next->p2_goAd;
cen=headSave->next->cen;
if(p1_take>0||p1_goAd>0)
p1TOp2=1;
else
p1TOp2=0;
if(p2_take>0||p2_goAd>0)
p2TOp1=1;
else
p2TOp1=0;
printf("操作流水%2d:",cen);
printf("%s%s",p1TOp2>0?"从p1":"",p2TOp1>0?"从p2":"");
printf("%s%s",p1_goAd>0?getName(p1_goAd):"",p1_goAd>0?"下船":"");
printf("%s%s",p1_take>0?getName(p1_take):"",p1_take>0?"上船":"");
printf("%s%s",p2_goAd>0?getName(p2_goAd):"",p2_goAd>0?"下船":"");
printf("%s%s",p2_take>0?getName(p2_take):"",p2_take>0?"上船":"");
if(headSave->next->next!=NULL)
printf("。之后行驶方向:%s%s
",p1TOp2>0?"p1->p2":"",p2TOp1>0?"p1<-p2":"");
else
printf("
");
headSave=headSave->next;
}
}
char*getName(intb)//获取对应名称
{
if(b==1000)
return"人";
elseif(b==100)
return"狼";
elseif(b==10)
return"羊";
elseif(b==1)
return"菜";
return"";
}
inttoShip(int*p1,int*p2,int*ship,boolf)//递归函数:上船人及任意一组合;lastTake:上一次承载物体,首次调用传0;f=0:p1->p2方向;1:反向。返回状态,1:方案可行;0:方案不可行;
{
inttake=-1,goAd,gdflag=1,cenSave;//take:上船物体。goAd:下船物体。gdflag:标识变量,p2判断能否直接下船,1能0不能
cenSave=++cen;
while(1)
{
goAd=*ship-1000;
if(f==0)//准备p1往p2
{
if(take==-1)
take=getFist(*p1);
*p1-=take;
*p1+=goAd;
gdflag=1;//标识置1,等到p2首先尝试直接卸货
}
else//准备p2往p1
{
if(take==-1&&gdflag==0)
{
take=getFist(*p2);
printf("开始尝试替换货物:
");
}
if(gdflag==1)//如果p2可以直接卸货
*p2+=goAd;
else//如果不能直接卸货,尝试带走一个同时卸货
{
*p2-=take;
*p2+=goAd;
}
}
printf("递归层级%d:假设%s从%s上船。%s下船,%s方向行驶。
",cenSave,take>0?getName(take):"无货物",f==0?"p1":"p2",goAd!=0?getName(goAd):"无货物",f==0?"p1往p2":"p2往p1");
if(beEaten(*p1,*p2))//如果发生被吃,假设失败,还原数据,选择下一假设
{
if(f==0)
{
*p1+=take;
*p1-=goAd;
}
else
{
if(gdflag==1)//p2点确定不能直接卸货,还原数据,标识置0
{
printf("----不能直接卸货,货物%s回到船上。",getName(goAd));
*p2-=goAd;
gdflag=0;
continue;
}
else//不能直接卸货并尝试替换货物失败,选择下一个货物替换
{
*p2+=take;
*p2-=goAd;
}
}
if(take==1)
{
printf("本次靠岸无可行的装卸方案,返回层级%d!
",cenSave-1);
return0;
}
take=take/10;//尝试选择下一个货物
continue;
}
else
{
if(f==1&&gdflag==1)//p2直接卸货假设成立船清空
*ship=1000;
else
*ship=1000+take;//换货假设成立货物装船
if(*p1==0)//如果已经完全转移
{
printf("所有货物过河成功!!
");
return1;
}
if(f==0)
addLog(take,goAd,0,0,cenSave);//生成流水日志
else
addLog(0,0,take,goAd,cenSave);//生成流水日志
if(toShip(p1,p2,ship,f==0?1:0))
{
return1;
}
else//由于下级失败,本回合重新选择
{
gdflag=0;
continue;
}
}
}
}
intgetFist(intpn)//获取物品组合中第一个
{
inti,count=0;
while(1)//上船物体从岸上第一个物体开始选择
{
if(pn<=1)
break;
pn=pn/10;
count++;
}
for(i=0;i<count;i++)
pn=pn*10;
returnpn;
}
intbeEaten(intp1,intp2)//检查是否发生被吃事件,发生返回1,未发生返回0
{
intren=0;
if(p1==110&&++ren==1)
printf("----河岸p1狼把羊吃了!重新选择
");
if(p2==110&&++ren==1)
printf("----河岸p2狼把羊吃了!重新选择
");
if(p1==11&&++ren==1)
printf("----河岸p1羊把菜吃了!重新选择
");
if(p2==11&&++ren==1)
printf("----河岸p2羊把菜吃了!重新选择
");
returnren;
}
❻ 关于人狼羊白菜过河的c语言编程题
先把羊运过去,再把草运过去,把羊接回来,把狼运过去,回去再把羊运过去
❼ 请用C语言编写:
我用一个类似的不过我没看明白
#include <stdio.h>
#include <stdlib.h>
#define maxloop 100 //最大层数,对于不同的扩展方法自动调整取值
#define pristnum 3
#define slavenum 3
struct SPQ
{
int sr,pr; //船运行一个来回后河右岸的野人、传教士的人数
int sl,pl; //船运行一个来回后河左岸的野人、传教士的人数
int ssr,spr; //回来(由左向右时)船上的人数
int sst,spt; //去时(由右向左时)船上的人数
int loop; //本结点所在的层数
struct SPQ *upnode ,*nextnode;//本结点的父结点和同层的下一个结点的地址
}spq;
int loopnum;//记录总的扩展次数
int openednum;//记录已扩展节点个数
int unopenednum;//记录待扩展节点个数
int resultnum;
struct SPQ *opened;
struct SPQ *oend;
struct SPQ *unopened;
struct SPQ *uend;
struct SPQ *result;
void initiate();
void releasemem();
void showresult();
void addtoopened(struct SPQ *ntx);
int search();
void goon();
int stretch(struct SPQ* ntx);
void recorder();
void main()
{
int flag; //标记扩展是否成功
for( ; ; )
{
initiate();
flag = search ();
if(flag == 1)
{
recorder();
releasemem();
showresult();
goon();
}
else
{
printf("无法找到符合条件的解");
releasemem();
goon();
}
}
}
void initiate()
{
int x;
char choice;
uend = unopened = (struct SPQ*)malloc(sizeof(spq));
if(uend==NULL)
{
printf("\n内存不够!\n");
exit(0);
}
unopenednum=1;
openednum=0;
unopened -> upnode = unopened; //保存父结点的地址以成链表
unopened -> nextnode = unopened;
unopened -> sr = slavenum;
unopened -> pr = pristnum;
unopened -> sl = 0;
unopened -> pl = 0;
unopened -> sst = 0;
unopened -> spt = 0;
unopened -> ssr = 0;
unopened -> spr = 0;
unopened -> loop = 0;
printf("题目:设有n个传教士和m个野人来到河边,打算乘一只船从右岸到左岸去。\n");
printf("该船的负载能力为两人。在任何时候,如果野人人数超过传教士人数,野人\n");
printf("就会把传教士吃掉。他们怎样才能用这条船安全的把所有人都渡过河去?\n");
printf("\n默认的n、m值皆为3\n");
for(;;)
{
printf("\n是否修改?(Y/N)");
scanf("%s",&choice);
choice=toupper(choice);
if(choice=='Y')
{
printf("\n请输入传教士人数");
for(;;)
{
scanf("%d",&x);
if(x>0)
{
unopened -> pr = x;
break;
}
else printf("\n输入值应大于0!\n请重新输入");
}
printf("\n请输入野人人数");
for(;;)
{
scanf("%d",&x);
if(x>0)
{
unopened -> sr = x;
break;
}
else printf("\n输入值应大于0!\n请重新输入");
}
break;
}
if(choice=='N')break;
}
}
int search()
{
int flag;
struct SPQ *ntx; //提供将要扩展的结点的指针
for( ; ; )
{
ntx = unopened; //从待扩展链表中提取最前面的一个
if(ntx->loop == maxloop)
return 0;
addtoopened(ntx); //将ntx加入已扩展链表,并将这个节点从待扩展链表中去掉
flag = stretch(ntx); //对ntx进行扩展,返回-1,0,1
if(flag == 1)
return 1;
}
}
int stretch(struct SPQ *ntx)
{
int fsr , fpr ; //在右岸上的人数
int fsl , fpl ; //在左岸上的人数
int sst , spt ; //出发时在船上的人数
int ssr , spr ; //返回时船上的人数
struct SPQ *newnode;
for (sst = 0 ; sst <= 2 ; sst++) //讨论不同的可能性并判断是否符合条件
{
fsr = ntx -> sr;
fpr = ntx -> pr;
fsl = ntx -> sl;
fpl = ntx -> pl;
if ((sst <= fsr) && (( 2 - sst) <= fpr))//满足人数限制
{
spt = 2 - sst;
fsr = fsr - sst;
fpr = fpr - spt;
if((fpr == 0) && (fsr == 0))//搜索成功
{
newnode = (struct SPQ*) malloc (sizeof(spq));
if(newnode==NULL)
{
printf("\n内存不够!\n");
exit(0);
}
newnode -> upnode = ntx; //保存父结点的地址以成链表
newnode -> nextnode = NULL;
newnode -> sr = 0;
newnode -> pr = 0;
newnode -> sl = opened -> sr;
newnode -> pl = opened -> pr;
newnode -> sst = sst;
newnode -> spt = spt;
newnode -> ssr = 0;
newnode -> spr = 0;
newnode -> loop = ntx -> loop + 1;
oend -> nextnode = newnode;
oend = newnode;
openednum++;
return 1;
}
else if ((fpr - fsr) * fpr >= 0) //判断是否满足传教士人数必须大于或等于野人人数
{
fsl = fsl + sst;
fpl = fpl + spt;
for (ssr = 0 ; ssr <= 1 ; ssr++) //返回
{
int ffsl , ffpl;
if ((ssr <= fsl) && ((1 - ssr) <= fpl))
{
spr = 1 - ssr;
ffsl = fsl - ssr;
ffpl = fpl - spr;
if ((ffpl - ffsl) * ffpl >= 0)
{ //若符合条件则分配内存并付值
int ffsr , ffpr;
ffsr = fsr + ssr;
ffpr = fpr + spr;
newnode = (struct SPQ*) malloc (sizeof(spq));
if(newnode==NULL)
{
printf("\n内存不够!\n");
exit(0);
}
newnode -> upnode = ntx; //保存父结点的地址以成链表
newnode -> sr = ffsr;
newnode -> pr = ffpr;
newnode -> sl = ffsl;
newnode -> pl = ffpl;
newnode -> sst = sst;
newnode -> spt = spt;
newnode -> ssr = ssr;
newnode -> spr = spr;
newnode -> loop = ntx -> loop + 1;
uend -> nextnode = newnode;
uend = newnode;
unopenednum++;
}
}
}
}
}
}
return 0;
}
void addtoopened(struct SPQ *ntx)
{
unopened = unopened -> nextnode;
unopenednum--;
if (openednum == 0 )
oend = opened = ntx;
oend -> nextnode = ntx;
oend = ntx;
openednum++;
}
void recorder()
{
int i , loop;
struct SPQ *newnode;
struct SPQ *ntx;
loop = oend -> loop;
ntx = oend;
resultnum = 0;
for( i = 0 ; i <= loop ; i++ )
{
newnode = (struct SPQ*) malloc (sizeof(spq));
if(newnode==NULL)
{
printf("\n内存不够!\n");
exit(0);
}
newnode -> sr = ntx -> sr;
newnode -> pr = ntx -> pr;
newnode -> sl = ntx -> sl;
newnode -> pl = ntx -> pl;
newnode -> sst = ntx -> sst;
newnode -> spt = ntx -> spt;
newnode -> ssr = ntx -> ssr;
newnode -> spr = ntx -> spr;
newnode -> nextnode = NULL;
ntx = ntx -> upnode;
if(i == 0)
result = newnode;
newnode -> nextnode = result;
result = newnode;
resultnum++;
}
}
void releasemem()
{
int i;
struct SPQ* nodefree;
for ( i = 1 ; i < openednum ; i++ )
{
nodefree = opened;
opened = opened -> nextnode;
free(nodefree);
}
for ( i = 0 ; i < unopenednum ; i++ )
{
nodefree = unopened;
unopened = unopened -> nextnode;
free(nodefree);
}
}
void showresult()
{
int i;
int fsr , fpr ; //在右岸上的人数
int fsl , fpl ; //在左岸上的人数
struct SPQ* nodefree;
printf("%d个传教士",result -> pr);
printf("%d个野人",result -> sr);
printf("%d个传教士",result -> pl);
printf("%d个野人",result -> sl);
for ( i = 1 ; i < resultnum ; i++ )
{
nodefree = result;
result = result -> nextnode;
free(nodefree);
printf("\n\n\t左岸人数 船上人数及方向 右岸人数\n");
printf("第%d轮\n",i);
fpl = result -> pl - result -> spt + result -> spr;
fpr = result -> pr - result -> spr;
fsl = result -> sl - result -> sst + result -> ssr;
fsr = result -> sr - result -> ssr;
printf("传教士%8d%8d\t<-\t%8d\n",fpl,result -> spt,fpr);
printf("野 人%8d%8d\t<-\t%8d\n",fsl,result -> sst,fsr);
printf("传教士%8d%8d\t->\t%8d\n",result -> pl,result -> spr,result -> pr - result -> spr);
printf("野 人%8d%8d\t->\t%8d\n",result -> sl,result -> ssr,result -> sr - result -> ssr);
}
printf("\n全体传教士和野人全部到达对岸");
free(result);
}
void goon()
{
char choice;
for(;;)
{
printf("是否继续?(Y/N)\n");
scanf ("%s" , &choice);
choice=toupper(choice);
if(choice=='Y')break;
if(choice=='N')exit(0);
}
}
❽ C语言编程!!!羊,狼,白菜,过河方法~!
过河的方法用语言表述是这样的:
第一次带羊过去,第二次带白菜过去同时带羊回来,第三次带狼过去,第四次带羊过去
❾ 有没有电脑编程高手帮我编个C++的程序,题目如下: 一个人带有一只羊, 一框菜和一只狼要过河, 但船上除了载
#include <stdio.h>
#include <string.h>
int visited[2][2][2][2];
int dfs(int p, int v, int s, int w)
{
if(visited[p][v][s][w]>=0)
return visited[p][v][s][w];
visited[p][v][s][w] = 0;
if(v==s&&s!=p)
return 0;
if(w==s&&w!=p)
return 0;
if(p==0&&v==0&&s==0&&w==0)
return 1;
if(dfs(1-p,v,s,w))
{
puts("人 自己到对岸");
visited[p][v][s][w] = 1;
return 1;
}
if(v==p&&dfs(1-p,1-v,s,w))
{
puts("人 和 菜 到对岸");
visited[p][v][s][w] = 1;
return 1;
}
if(w==p&&dfs(1-p,v,s,1-w))
{
puts("人 和 狼 到对岸");
visited[p][v][s][w] = 1;
return 1;
}
if(s==p&&dfs(1-p,v,1-s,w))
{
puts("人 和 羊 到对岸");
visited[p][v][s][w] = 1;
return 1;
}
return 0;
}
int main()
{
memset(visited,-1,sizeof(visited));
dfs(1,1,1,1);
return 0;
}
输出:
人 和 羊 到对岸
人 自己到对岸
人 和 狼 到对岸
人 和 羊 到对岸
人 和 菜 到对岸
人 自己到对岸
人 和 羊 到对岸
#include <stdio.h> #include <string.h> int visited[2][2][2][2]; int dfs(int p, int v, int s, int w) { if(visited[p][v][s][w]>=0) return visited[p][v][s][w]; visited[p][v][s][w] = 0; if(v==s&&s!=p) return 0; if(w==s&&w!=p) return 0; if(p==0&&v==0&&s==0&&w==0) return 1; if(dfs(1-p,v,s,w)) { puts("人 自己到对岸"); visited[p][v][s][w] = 1; return 1; } if(v==p&&dfs(1-p,1-v,s,w)) { puts("人 和 菜 到对岸"); visited[p][v][s][w] = 1; return 1; } if(w==p&&dfs(1-p,v,s,1-w)) { puts("人 和 狼 到对岸"); visited[p][v][s][w] = 1; return 1; } if(s==p&&dfs(1-p,v,1-s,w)) { puts("人 和 羊 到对岸"); visited[p][v][s][w] = 1; return 1; } return 0; } int main() { memset(visited,-1,sizeof(visited)); dfs(1,1,1,1); return 0; }
❿ 人狼羊草过河问题 船需人划,最多载一物.试安排他们过河
设目的地为南 另一端为北
先把羊从北岸运到南岸,此时北岸剩狼和草,
然后人自行驾船回北岸,将草运装船运到南岸
到南岸之后将草卸下,载上羊返回北岸
到北岸卸下羊 装上狼,将狼载上运到南岸
到南岸卸下,此时南岸剩狼和草
空载驾船到北岸 装上羊 返回南岸