关于理解约瑟夫环应用题代码

发布时间:2024-03-03 21:03:48

题目:

有二十九个女生(分别用1-29号来称呼)围成一圈玩报数游戏,规则是这样的:从1开始数数,当数到3的这个人就退出游戏,而她后面的人接着从1数。。。如此一直到最后剩下一个人,现在知道最初是从13号女生开始的游戏,问最后剩下的会是第几号女生?

要求:

1用批处理解答

2代码简洁高效

3代码通用且不生成临时文件

加分原则:

以思路为重(如思路独特,请简要说明)

完全符合要求的加10分

已有两套解决方案,见3楼more和6楼ieutk版主的代码,但个人认为这两套方案均不完美(见本人的跟贴评述),期

待完美方案的出现,大家加油了!!!

注:约瑟夫问题

约瑟夫问题是个有名的问题:n个人围成一圈,从第一个开始报数,第m个将被杀掉,最后剩下一个,其余人都将被杀掉。例如n=6,m=5,被杀掉的人的序号为5,4,6,2,3。最后剩下1号。

more:

复制代码代码如下:

@echooff

set"str=1314151617181920212223242526272829123456789101112"

:again

for/f"tokens=1,2,4*"%%ain("%str%")do(

ifnot"%%c"==""(set"str=%%c%%d%%a%%b"&goto:again)else(echo%%b&pause&exit)

)

ieutk:

复制代码代码如下:

@echooff

setlocalenabledelayedexpansion

for/l%%ain(12-11)doset"str=%%a!str!"

for/l%%ain(29-113)doset"str=%%a!str!"

:main

set"ie=0"

for%%ain(%str%)doset/aie+=1

if%ie%neq1(

for%%ain(%str%)do(

set/anum+=1

if!num!equ3(

set"num=0"

set"str=!str:%%a=!

)

)

gotomain

)

echo%str%

pause

batman:

复制代码代码如下:

@echooff&setlocalenabledelayedexpansion

for/l%%ain(13,1,29)doset"str=!str!#%%a#"

for/l%%ain(1,1,12)doset"str=!str!#%%a#"

:lp

for%%ain(!str!)do(

set/an+=1

if!n!equ3set"str=!str:%%a=!"&set/an=0

)

for/f"tokens=2"%%ain("%str%")doif"%%a"neq""gotolp

echo最后剩下的是%str:#=%号&pause>nul

第2篇:C语言用数组解决约瑟夫环问题

问题说明:

在罗马人占领乔塔帕特后,39个犹太人与约瑟夫及他的朋友躲到一个洞中,大家决定宁愿自杀也不要被敌人抓到,于是确定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而约瑟夫和他的朋友并不想死去,那么他应该怎样安排他和他的朋友的位置,才能逃脱这场死亡游戏呢?

有N个编号为1~N的人围成一圈,现在每隔两个人(比如:1、4之间隔了2、3)就将一个人淘汰出去,问最后剩下的是编号为几的人?

算法代码如下:

#include

#include

intmain(void)

{

intpeople_count=0;

int*peoples=NULL;

printf("pleaseinputpeoplenumber:");

scanf("%d",&people_count);

if(people_count<2){

printf("can'tdoJoseph\n");

}

peoples=(int*)calloc(people_count,sizeof(int));

inti;

for(i=0;i<people_count;i++){

peoples[i]=i+1;

}

i=0;

intj=0;

intrest=people_count;

while(rest){

if(i>=people_count){

i%=people_count;

}

if(peoples[i]==0){

i++;

continue;

}

if(j++%3==0&&rest>1){

printf("killpeopleNO.%d\n",peoples[i]);

peoples[i]=0;

rest--;

}elseif(rest==1){

printf("NO.%disalive\n",peoples[i]);

rest--;

}

i++;

}

system("pause");

return0;

}

第3篇:关于应用物理知识解题

初中物理教学中,常会出现应用物理题,令有些同学无所适从,如果能在求解时加以识别、转化实际问题为物理问题,就不难解了,以下是常用的几种途径,应用物理知识解题六化。

一、对照转换,实际问题规范化

如图所示,甲、乙两个容器等重,底面积相同,内装有同一深度的水,水平放置在桌面上,①比较甲、乙两容器底部受到的压力和压强的大小;②比较甲、乙两容器对桌面的压力和压强的大小;

甲乙

这是一道有关容器底部压力和压强的习题。因为容器底有两个面,上表面和液体接触,所以是液体的压力和压强问题;下表面和桌面接触,所以是固体的压力和压强问题。解答此类问题,要反复用到公式p=f/s和p=ρgh。那么在比较其压力和压强时,其思路如何呢?

从液体压强公式p=ρgh可以看出,液体的压强只跟液体的密度有关,跟液重无关,再由f=ps=ρghs可知,液体对容器底部的压力也跟液重无关,所以比较液体对容器底部的压力和压强时,不管容器的形状如何,一般应先由公式p=ρgh比较出液体对容器底部的压强,然后由公式f=ps比较其压力。

容器连同它所盛的液体都支承在桌子上,对桌子的压力就等于它们的总重,而压强则是单位面积上受到的压力。因此要比较容器对桌面的压力和压强,应当比较它们对支承物的压力,然后再由公式p=f/s比较其压强。

弄清此类问题的思路,问题也就迎刃而解了。

二、抓住本质,研究对象模型化

如图,一重为500牛,半径为0.5米的车轮f

放在高为30厘米的台阶旁,车轮与台阶接触a

处是粗糙的,教育论文《应用物理知识解题六化》。要想将车轮刚能开始向台阶上o

滚,所用的最小力应为多少?作用在何处?

方向如何?g

分析:本题中隐蔽条件有:1车轮与台阶接触处是粗糙的;2车轮刚能开始向台阶上滚即已知“地面对车轮的支持力为零”;3对车轮施以最小的力即已知所施力的力臂最长;至此,已知条件皆已明确,根据杠杆的平衡条件不难求解。

解:根据以上分析,如图所示,力作用于a点,且力的方向垂直于ao其大小可根据杠杆平衡条件得:f.2r=g.l

l=r=0.5

g=500牛,h=0.3米代人得:f=229牛

再比如有例如下:电热器淋浴器分为储水式和无水箱式两种。储水式淋浴器要用较长时间把水箱中的水加热,待水温达到要求后用水箱中的热水淋浴。无水箱式淋浴器使冷水流过电热器就达到要求的温度而立即从喷头流出供淋浴。已知冷水的温度为16℃,淋浴所需的热水温度为38℃,淋浴所需热水流量为4×10-3米3/分,水的比热是4.2×103焦耳/(千克.℃),家庭电路允许通过的最大电流为5a。请你利用以上数据通过计算说明家庭中不宜使用无水箱式电热淋浴器。

分析:本题是热电综合题,从题给条件可知,每秒钟所需热水的体积和每秒钟所需热水的质量,从而求知每秒钟将水加热所需的热量。从题目看,为说明家庭中不宜使用无水箱式电热淋浴器,可以从电流考虑,看实际电流是否超过允许通过的最大电流5a。此题就变成“要使流量为4×10-3米3/分的水从16℃升高到38℃,所需的家庭电路的电流是多少?”

解:每秒钟所需加热的水的质量

m=ρv=1.0×103千克/米3×(4×10-3×1/60)米3=6.67×10-2千克

每秒钟将水从16℃加热到38℃所需的热量

q=cm(t-t0)=4.2×103×6.67×10-2×(38-16)焦=6163焦

因为p=ui所以i=p/u=q/ut=6163/220a=28a>>5a

∴家庭不宜使用无水箱式电热淋浴器。

三、细致分析,模糊目标清晰化

例1烧水至沸腾时,壶口的“白汽”是()

a)水蒸气b)水汽c)小水珠d)水蒸气和水的混合物

分析:初二学生常选水蒸气,但正确*却是小水珠。因为水蒸气是一种无*无味的看不见的气体,而壶口的白汽是看得见的,它是水蒸气遇冷液化而成的小水珠悬浮在空中。

例2离开*口的子*受到()力的作用。(空气阻力忽略不计)

a)只有重力b)有重力和推力c)有惯*d)不受力

分析:学生往往选b,也有的选c,

第4篇:约瑟夫问题数学故事

有一个古老的传说,有64名战士被敌人俘虏了,敌人命令它们排成一个圈,编上号码1,2,3,……64。敌人把1号杀了,又把3号杀了,他们是隔一个杀一个这样转着圈杀。最后剩下一个人,这个人就是约瑟夫,请问约瑟夫是多少号?

这就是数学上有名的“约瑟夫问题”。给大家一个提示,敌人从l号开始,隔一个杀一个,第一圈把奇数号码的战士全杀死了。剩下的32名战士需要重新编号,而敌人在第二圈杀死的是重新编排的'奇数号码。按照这个思路,看看你能不能解决这个问题?

*解析:

由于第一圈剩下的全部是偶数号2,4,6,8,……64。把它们全部用2除,得1,2,3,4,……32.这是第二圈重新编的号码。第二圈杀过之后,又把奇数号码都杀掉了,还剩下16个人。如此下去,可以想到最后剩下的必然是64号。

64=2×2×2×2×2×2,它可以连续被2整除6次,是从1到64中质因数里2最多的数,因此,最后必然把64号剩下。从64=2×2×2×2×2×2还可以看到,是转过6圈之后,把约瑟夫斯剩下来的。

【约瑟夫问题数学故事】相关文章:

1.约瑟夫问题小学趣味数学故事

2.约瑟夫问题与因式分解小学生数学故事

3.约瑟夫的问题小学趣味数学故事

4.约瑟夫问题与因式分解的小学数学故事

5.数学故事问题

6.女生散步问题数学故事

7.牛顿问题趣味数学故事

8.口香糖问题的趣味数学故事

第5篇:关于c语言约瑟夫问题输出序号算法

约瑟夫问题

#include#includetypedefstructnode{intdata;structnode*next;}LNode,*LinkList;intYSF(LinkListm,intn,intl);voidmain(){intx,y,z;LinkListp,q,r;//p用来指向第一个人,r、q用来实现尾插法构建链表p=(LinkList)malloc(sizeof(LNode));printf("请输入总人数:");scanf("%d",&x);printf("请输入报数大小:");scanf("%d",&y);printf("请输入报数开始人序号:");scanf("%d",&z);r=p;for(inti=1;i<=x-1;i++){q=(linklist)malloc(sizeof(lnode));r->data=i;r->next=q;r=q;}//创建x个单链表q->data=x;q->next=p;//构成循环链表for(intj=1;j<=z-1;j++){p=p->next;}//找到开始报数人printf("请输入序号:");into;scanf("%d",&o);YSF(p,y,o);}intYSF(LinkListm,intn,intl){while(m->next!=m){for(intk=1;knext;}ints=1;if(l==s){printf("编号为%d的人出列",m->next->data);break;}else{n++;}m->next=m->next->next;//剔除满足报出y人的结点m=m->next;}if(m->next==m)printf("编号为%d的人出列",m->data);return0;}

第6篇:关于约瑟夫问题与因式分解小学生数学故事

有一个古老的传说,有64名战士被敌人俘虏了,敌人命令它们排成一个圈,编上号码1,2,3,……64。敌人把1号杀了,又把3号杀了,他们是隔一个杀一个这样转着圈杀。最后剩下一个人,这个人就是约瑟夫,请问约瑟夫是多少号?

这就是数学上有名的“约瑟夫问题”。给大家一个提示,敌人从l号开始,隔一个杀一个,第一圈把奇数号码的战士全杀死了。剩下的32名战士需要重新编号,而敌人在第二圈杀死的是重新编排的奇数号码。按照这个思路,看看你能不能解决这个问题?

*解析:

由于第一圈剩下的全部是偶数号2,4,6,8,……64。把它们全部用2除,得1,2,3,4,……32.这是第二圈重新编的号码。第二圈杀过之后,又把奇数号码都杀掉了,还剩下16个人。如此下去,可以想到最后剩下的必然是64号。

64=2×2×2×2×2×2,它可以连续被2整除6次,是从1到64中质因数里2最多的数,因此,最后必然把64号剩下。从64=2×2×2×2×2×2还可以看到,是转过6圈之后,把约瑟夫斯剩下来的。