C语言编程,编号1,2,3……,n的人循环报数,报数为m的出列,下一位接着又从1开始报数,输出最后一个编号

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言编程,编号1,2,3……,n的人循环报数,报数为m的出列,下一位接着又从1开始报数,输出最后一个编号相关的知识,希望对你有一定的参考价值。

我自己写的程序,不知道问题在哪,运行验证时,对应某些n,m值,得到的是对的,有些又是错的,急求指导,我的编程软件调试的时候总是出问题,急求指导,我想把程序写简单点
#include<stdio.h>
void main()

int num[50],n,m,i;
int x=0,y=0;

printf("总数,报数\n");
scanf("%d,%d",&n,&m);

for(i=0;i<=n;i++)


if(i==n)//编号为n+1个人报数时,因为只有n个人,所以重新由第一个人报数

i=0;//i=0,相当于第一个人开始报数

num[i]=i+1;//编号1,2,3,……,n

if((n-y)==1) //如果只剩1个人未报数,即为最后一个出列的人


printf("%d",i+1);//输出最后一个出列人的编号

break;//跳出循环


if(num[i]!=0)//编号不为0的报数

x++;//x控制报的数

if(x==m)//报数为m时

x=0;//报数归零,实现循环报数

num[i]=0;//编号变为0,这样处理相当出列,编号为0的不参与报数

y++;//出列人数+1





指出一个显而易见的错误。为num数组 赋编号怎么可以和其他判断放在一起呢
PLUS:
以下为我用Java 在你的基础上修改的,你本身程序思路是对的,加星号×的是有修改过的地方,特别注意最后一段代码,仔细想想吧,就不告诉你为什么了。语法和c差不对你应该能懂得哈

public class rerere
/**
* @param args
*/
public static void main(String[] args)

int[]num=new int[50];int n=7,m=3;
int x=0,y=0;
int i;

//*************************先赋值
for(int j=0;j<n;j++)

num[j]=j+1;

//*************************
for( i=0;i<=n;i++)

if(i==n)//编号为n+1个人报数时,因为只有n个人,所以重新由第一个人报数

i=0;//i=0,相当于第一个人开始报数

if(num[i]!=0)//编号不为0的报数

x++;//x控制报的数

if(x==m)//报数为m时

x=0;//报数归零,实现循环报数
System.out.println(num[i]+"变为0");//××××××××××××方便查看
num[i]=0;//编号变为0,这样处理相当出列,编号为0的不参与报数

y++;//出列人数+1


//××××××××××××××××××××××××××××××××××这时候不能简单的以为i+1就是最后剩下的那位,慢慢理解
if((n-y)==1) //如果只剩1个人未报数,即为最后一个出列的人

//printf("%d",i+1);//输出最后一个出列人的编号
for(int ii=0;ii<n;ii++)

if(num[ii]!=0)

System.out.println(num[ii]);break;//跳出循环



if((n-y)==1)//××××××××××××××××××××跳出最外层循环
break;
//×××××××××××××××××××××××××××××××××××××××××××


参考技术A 其实结果就是n%m(模运算)也就是n/m的余数
如果求余结果为0 那么最后一个认得编号是m追问

能看看我的程序吗?

参考技术B

/*

总数 报数

8 4

4 8 5 2 1 3 7 6

Press any key to continue

*/

#include<stdio.h>
void main() 
int num[50],n,m,i,j;
int len,start = 0,counter = 1;
printf("总数 报数\\n");
scanf("%d%d",&n,&m);
if(n < 0 || n > 50 ) n = 50;
if(m < 1 || m > n) m = n/2;
for(i = 0; i < n; ++i) num[i] = i + 1; // 预填
len = n; // len保留队列中现有人数
while(len) 
if(counter == m) 
printf("%d ",num[start]);
for(j = start; j < len - 1; ++j)
num[j] = num[j + 1];
--len;
counter = 1;

else 
++counter;
++start;
start %= len;


printf("\\n");

追问

能看看我的程序吗?

追答

我仔细看了你的代码,算法上不合理,所以改动很大。这是用数组做的,我还有链表做的约瑟夫报数代码,看上去要复杂多了。

本回答被提问者采纳

详解约瑟夫环问题

约瑟夫问题:n个人围坐成一圈,从1开始顺序编号;游戏开始,从第一个人开始由1到m循环报数,

报到m的人退出圈外,问最后剩下的那个人原来的序号。

 

问题分析:面对这样循环报数的数据,我们最容易想到的就是用数组进行报数的模拟,最后把存活的人的编号输出。

先贴上这种思路的代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>  // find() 函数
 6 
 7 int main(){
 8     int m,n;
 9     cin>>n>>m;
10     vector<bool> s(n, 1);
11     int dead(0), cnt(0);
12     auto it=s.begin();
13     while(dead < n-1){
14         if(it == s.end())   it = s.begin();
15         if(*it) cnt++;
16         if(cnt == m){
17             *it = 0;
18             cnt = 0;
19             dead++;
20         }
21         it++;
22     }23     it=find(s.begin(), s.end(), 1);
24     cout<<it-s.begin()+1;
25     return 0;
26 }

 

代码思路是采用 vector<bool> 容器来存储每一个人的存在状态,如果在圈内参与报数,则值为1,退出圈后为0 。dead 是退出圈不参与报数的人数,作为报数停止的条件,即当 dead == n-1 时,报数停止。cnt 是每一个人报的数,当 cnt == m 时,报该数的人退出圈不再参与报数,在vector数组中的位置变为 0。

第十行,使用vector的迭代器来表示报数成员所对应的下标,while循环中即报数的模拟过程。

第十四行,因为迭代器运行过程中,可能指向 s.end() ,这一位置并不在vector 内,且没有有意义的数据,于是把迭代器重新指向 s.begin() ,这一过程解决了环形报数中第一个人和最后一个人连接的问题。

第十五行,表示报数过程,vector 数组中,此成员参与报数的话,cnt++ ,模拟报数的进行。

第十六行开始,遇到报到 m 的人,vector 中所对应的数据变为0,dead++ ,表示不再参与报数。cnt 置 0 ,表示所报数字重新从1开始(为什么不让cnt=0:因为下一个人出现时,才会自增1)。

第二十三行,得到最后那个人的迭代器指向。由于 vector 迭代器是随机访问迭代器,支持加减运算,所以刚才得到的迭代器指向减去 s.begin() ,就是最后留下的人所对应的下标(为什么不是他的原序号:因为下标从 0 开始计数),该结果再加一就是最后留下的人的原序号。

 

模拟的效率似乎不是很高,而且代码量也不算少,那有什么简单的办法呢?

先贴代码:

  递归调用:

#include<iostream>
#include<cstdio>
int joseph(int n, int m){
    return n==1 ? 0 : (joseph(n-1, m)+m)%n;
}
int main(){
    int m,n;
    cin>>n>>m;
    cout<<joseph(n, m) +1;
    return 0;
}

 待续...

以上是关于C语言编程,编号1,2,3……,n的人循环报数,报数为m的出列,下一位接着又从1开始报数,输出最后一个编号的主要内容,如果未能解决你的问题,请参考以下文章

SZTUOJ 1005.报数游戏

.N个人站成一排,从左到右编号为1-N,从左到右报数"1,2,3,……",其中报数为1和2的人出列

ACM--模拟--nyoj 559--报数游戏--湖南第七届省赛

人类高质量代码解约瑟夫环问题

详解约瑟夫环问题

约瑟夫环杂题