读书人

c语言的一个关于约瑟夫的有关问题各

发布时间: 2012-05-07 12:40:40 作者: rapoo

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的问题 可改动一些数字 既可实现

读书人网 >C语言

热点推荐