过河c语言
1. 求狼羊白菜过河的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;
}
2. 求:C语言课设游戏青蛙过河源代码!
设n为石墩数,m为荷叶数 ,设F[n,m]表示当有n个石墩,m个荷叶时,能跳过去的最多青蛙数,我们现在可以增加一个石墩,此时就有n+1个石墩了,把第n+1个石墩看成右岸,这样就可以把F[n,m]个青蛙从左岸跳到第n+1个石墩上(借助原来河里的n个石墩,m个荷叶), 这时第n+1个石墩上就有F[n,m]个青蛙了,此时河里还有n个空石墩,m个空荷叶,还可以帮助F[n,m]个青蛙从左岸跳到真正的右岸,此时再把第n+1个石墩看成左岸, 借助河里的n个石墩,m个荷叶,顺利的跳到右岸青蛙的身上.至此一共可以跳过去 2*F[n,m]个青蛙.
由此可知: 关系式 F[n+1,m]=2*F[n,m]
推导: F[n,m]=2*F[n-1,m]
=4*F[n-2,m]
……
=(2^i)*F[n-i,m]
……
=(2^n)*F[0,m]
当n=0时,河里只有m个荷叶,每个叶上只能有一个青蛙,再加上从右岸可以直接跳到左岸的一只,所以共有m+1个青蛙,即F[0,m]=m+1;所以
F[n,m]=(m+1)*2^n
3. C语言问题 过河
sunlight12346正解,不过还可以优化一下
构造一个updateMin函数,功能为,计算青蛙从x开始跳到L所需要踩的石子数,如果结果比当前计算得到的最小数curMin小,则返回计算结果,如果大于等于curMin,则返回curMin,通过递归计算最终的最小值。可以稍作剪枝,如果递归过程中,已踩的石子数stepedStNum已经大于等于curMin,那么就返回curMin,不必要再继续计算下去。
#include <stdio.h>
void main()
{
int x, s, t, l, curMin, stoneNum, i, temp;
int stoneLoc[100]={0};
int stepedStNum = 0;
x = 0;
printf("Input the length of bridge:");
scanf("%d",&l);
printf("Input the range of distance:");
scanf("%d%d",&s,&t);
printf("Input the number of stone:");
scanf("%d",&stoneNum);
for ( i=0; i<stoneNum; i++)
{
scanf("%d", &stoneLoc[i]);
}
curMin = l;
curMin = updateMin(x, stepedStNum, s, t, l, stoneLoc, stoneNum, curMin);
printf("%d", curMin);
}
int updateMin(int x, int stepedStNum, int s, int t, int l, int stoneLoc[], int stoneNum, int curMin)
{
int i = 0;
if (x >= l)
{
return stepedStNum;
}
for (i=0; i<stoneNum; i++)
{
if (stoneLoc[i] == x)
{
stepedStNum++;
break;
}
}
if (stepedStNum >= curMin)
{
return curMin;
}
for (i=t; i>=s; i--)
{
curMin = updateMin(x+i, stepedStNum, s, t, l, stoneLoc, stoneNum, curMin);
}
return curMin;
}
4. C语言代码 过河智力游戏
#include <stdio.h>#define MAX 100typedef enum BOOL{ FALSE = 0, TRUE = 1 }BOOL。
typedef union Items{struct {char boy : 1;char girl : 1;char boys)。
语言特点
主要特点
C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试,且c语言的处理和表现能力都非常的强大,依靠非常全面的运算符和多样的数据类型,可以轻易完成各种数据结构的构建。
通过指针类型更可对内存直接寻址以及对硬件进行直接操作,因此既能够用于开发系统程序,也可用于开发应用软件。通过对C语言进行研究分析,总结出其主要特点如下:
(1)简洁的语言
C语言包含的各种控制语句仅有9种,关键字也只有32个,程序的编写要求不严格且以小写字母为主,对许多不必要的部分进行了精简。
实际上,语句构成与硬件有关联的较少,且C语言本身不提供与硬件相关的输入输出、文件管理等功能,如需此类功能,需要通过配合编译系统所支持的各类库进行编程,故c语言拥有非常简洁的编译系统。
(2)具有结构化的控制语句
C语言是一种结构化的语言,提供的控制语句具有结构化特征,如for语句、if...else语句和switch语句等。可以用于实现函数的逻辑控制,方便面向过程的程序设计。
(3)丰富的数据类型
C语言包含的数据类型广泛,不仅包含有传统的字符型、整型、浮点型、数组类型等数据类型,还具有其他编程语言所不具备的数据类型,其中以指针类型数据使用最为灵活,可以通过编程对各种数据结构进行计算。
以上内容参考:网络-C语音