职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 789|回复: 1

计算机三级上机约瑟夫环

[复制链接]
释迦牟尼 发表于 2009-8-18 11:24 | 显示全部楼层 |阅读模式
设有n个人围坐一圈并按顺时针方向从1到n编号,从第s个人开始进行1到m的报数, 报数到第m个人, 此人出圈, 再从他的下一个人重新开始1到m的报数,如此进行下去直到所有的人都出圈为止
现要求按出圈次序,给出这n个人的顺序表p
请考生编制函数Josegh()实现此功能并调用函数WriteDat()把编号按照出圈的顺序输出到OUT.DAT文件中
注意:第1个出圈的编号存放在p[0]中,第2个出圈的编号存放在p[1]中,直至第n个出圈的编号存放在p[n-1]中
设 n = 100, s = 1, m = 10进行编程
注意: 部分源程序存放在PROG1.C中
请勿改动主函数main()和输出数据函数WriteDat()的内容
#include <stdio.h>
#define N 100
#define S 1
#define M 10
int p[100], n, s, m ;
void WriteDat(void) ;
void Josegh(void)
{
}
void main()
{
m = M ;
n = N ;
s = S ;
Josegh() ;
WriteDat() ;
}
void WriteDat(void)
{
int i, j = 0 ;
FILE *fp ;
fp = fopen(\"out.dat\", \"w\") ;
for(i = 0 ; i <= N - 1 ; i++) {
printf(\"%4d \", p) ;
fprintf(fp, \"%4d\", p) ;
j++ ;
if(j % 10 == 0) {
printf(\"\\n\") ;
fprintf(fp, \"\\n\") ;
}
}
fclose(fp) ;
}
答案是这样的
int i,j,s1,w,q[100];
for(i=0;i<n;i++)q=0;
s1=s;
for(i=1; i<=n; i++)p[i-1]=i;
for(i=n; i>=2; i--)
{ s1=(s1+m-1)%i;
if(s1==0) s1=i;
w=p[s1-1];
for(j=s1; j<i; j++)p[j-1]=p[j];
p[i-1]=w;
}
不理解为什么下一个开始报数的编号是(s1+m-1)%i.比如当i=100时
s1=(1+10-1)%100=10
但是报数是从1开始报
编号为10的人数到10他是第一个出圈的人
下面接着重新开始报数的应该是编号为11的人啊
请问为什么应该是(s1+m-1)%i这个表达式呢?
dzzl 发表于 2009-8-18 11:24 | 显示全部楼层

计算机三级上机约瑟夫环

约瑟夫环有好多种解法
但是大体的可以分为两类:
1. 将符合出圈要求的人进行标注
但是不出圈
只是下次再轮到此人时
直接跳过
不参加报数
2. 将符合出圈要求的人直接出圈(从环中删除)
剩下的人继续报数

这里列的是第二种方法

出圈的处理在这里: p[i-1]=i;
由于已经有人出圈
所以编号也就得-1了:(s1+m-1)%i
您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-4-20 21:00 , Processed in 0.139508 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表