c语言的一个关于约瑟夫的问题,各位看看我编的对不对
关于一个约瑟夫的问题:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。
程序编出的结果是a结构中flog为0的人是不被扔入大海的,既将教徒编为flog为1的记录,请各位帮我看看我编的对不对,代码如下:
#include<stdio.h>
struct a{
int num;
int now;
int flog;
}a[31]; //a为记录的结构体,num为原始编号,now为每次扔人后的编号,flog为是否扔下的标识
static int count=0;
void record() //向结构体中写入记录
{
int i;
for(i=1;i<31;i++)
{
a[i].num=i;
a[i].flog=1;
a[i].now=i;
}
}
void reng() //扔人
{
int i,j,m;
while(count<15)
{
for(i=1;i<31;i++)
{
if(a[i].now % 9 == 0 && a[i].flog==1)
{
a[i].flog=0;
count++;
}
}
for(j=1;j<31;j++)
if(a[j].flog==0) for(m=j+1;m<31;m++)
a[m].now--;
}
}
void xian() //显示
{
int i;
printf("num flog\n");
for(i=1;i<31;i++)
{
printf("%5d %5d\n",a[i].num,a[i].flog);
}
}
void main()
{
record();
reng();
xian();
}
[解决办法]
不对,你对问题理解的不对,约瑟夫问题是从1-9,后9被扔掉后是从10号开始继续报数的,如果还是从1号报数,傻瓜都知道站在1-8位怎么也死不了的
用循环链表的方法是最简单的
做一个循环链表,然后依次NEXT,到累加9次就了就设置被人的标志,然后依次下去,就这么简单
[解决办法]
不对,刚才看错了,不好意思,你是轮了一圈之后又从1开始了
在这里也就是从1-9 10-18 19-27后 又从1开始了,其实应该是从28开始的,你的代码是有问题的
如果你一定要用数组的话也可以
- C/C++ code
void reng() //扔人{ int i,m; int cnt =0; for(i = 1; i < 31; i++) { if(a[i].flog==1) { cnt++; if(cnt == 9) { a[i].flog=0; cnt = 0; count++; if(count >=15) { break; } } } if(i == 30) { i = 0; } }}
[解决办法]
- C/C++ code
//假设有n个人团团围做,从第1个人开始数数,数到第m个人时候,第m个人出列,//然后继续从1开始数数,数到第m个人退出#include <stdio.h>#include <conio.h>int i,k,t;int n,m;static char f[1001];//0该座位未出圈,1该座位已出圈void main() { while (1) { printf("Input n m(1000>=n>=m>=1):"); fflush(stdout); rewind(stdin); if (2==scanf("%d%d",&n,&m)) { if (1000>=n && n>=m && m>=1) break; } } t=0;//已出圈总人数 i=1;//座位编号 k=1;//当前要数的数 while (1) { if (0==f[i]) { if (m==k) { t++; f[i]=1; printf("%3d ",i); if (0==t%10) printf("\n"); if (t>=n) break; } k++;if (k>m) k=1; } i++;if (i>n) i=1; } cprintf("Press any key ..."); getch();}
[解决办法]
约瑟夫环 问题
使用数组 状态位思想
#include <stdio.h>
#define N 10 //N 为总人数
int main(void)
{
char array[N] = {0}; //初始化一空数组
int i = 0;
int interval = 4; //间隔 既数到间隔数者 退出
int out_couter = 0;
int total_num = 0; //退出者的总人数
for (i = 0; total_num < N - 1; i++) //此循环结束 必剩余最后一个数
{
if (i == N) //实现数组的循环
{
i = 0;
}
if (array[i] == 0)
{
out_couter++;
}
if (out_couter == interval)
{
out_couter = 0;
array[i] = 1; // 将退出的数在数组中标价
printf("%5d(out)\n",i+1); //并输出 退出者的号码
total_num++; //退出人数加 1
}
}
for (i = 0; i < N; i++)
{
if (array[i] == 0)
{
printf("the last people is %d\n", i + 1);
}
}
return 0;
}
LZ的问题 可改动一些数字 既可实现