智者生存

来源:互联网 发布:数码快照软件 编辑:程序博客网 时间:2024/04/29 21:47

 

       17世纪法国数学家加斯帕的一本《数学的游戏问题》描述了许多有趣问题,约瑟问题就是其中之一:

       15名基督教徒和15名异教徒同乘一船航行,途中风浪大作,危机万分,领航者告诉大家,只要将全船的一半人投入海中,其余人就能幸免。大家都同意这个办法,并协定者30人围成一圈;由第一个人起报数,每数至第9人便把他投入海中,下一个接着从1开始报数,第9人又被投入海中,依次循环,直至剩下15人为止。问题是如何排法使投入海中的人全为异教徒?

我们现在来用C++来解决这个简单的问题。

用c++模拟当时的情况,我的思路是,30个人全部都是基督教徒,选出15个“叛变”成为异教徒,然后踹他们下海。先用数组将这30个人排列出来(0代表基督教徒,1代表异教徒)

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

考虑到这30个人是围成一个圆形的,所以不建议使用for语句,选择while更简单和便于理解(我在一开始的时候也是用的for语句,在30个人围成圈的情况下我用了另外一个数组来互相替换,将30个人变成60个,虽然最后也实现了,但是代码比用while的长了一倍)

代码如下:

#include<iostream>
using std::cout;
using std::endl;
int main()
{
 int num[30]={0};
 int m,k,i;
 m=0;//m代表选出来的人数
 k=0;//k代表循环控制器
 i=0;//i用来模拟圆圈
 while(m<15)
 {
  if(num[i]!=1) k++;
  if(k==9)
  {
   num[i]=1;//选出一个异教徒,踢他下水
   k=0;//循环控制器初始为0
   m++;//记录异教徒人数
  }
  i++;
  if(i==30) i=0;
 }
 int ship[15],sea[15];//ship代表留在船上的基督教徒,sea代表异教徒
 int i2=0,i3=0;
 for(int i1=0;i1<30;i1++)
 {
  if(num[i1]==0)
  {
   ship[i2]=i1+1;
   i2++;
  }
  else
  {
   sea[i3]=i1+1;
   i3++;
  }
 }
 cout<<"基督教徒应该站在";
 for(int i4=0;i4<15;i4++)
 {
  cout<<ship[i4]<<" ";
 }
 cout<<"的位置上。";

 return 0;
}
按照编程的习惯应该把main定义成viod类型的,但是为了最后展示的效果,用了int。有图有真相

图片

发这个帖子希望和大家交流一下,有更简洁的思路请给我留言。

原创粉丝点击