The classic problem of Joseph's problem_C language implementation

<Joseph Question>

1. Brief description of the problem

The Joseph problem is also called Joseph ring, which is a mathematical application problem.

It is known that there are n people (respectively numbered 1, 2, 3...n) sitting in a circle, starting from the first person to report the number, and the number of people who report to the number m go out of the circle; then start from the next person to report again and report The person with m goes out of the circle; the game ends when the last person is left. Output the original number of the remaining person.

2. Question thinking

The problem we want to solve:

  • The person who reports to m is out of the circle, how to indicate that he is out of the circle?
  • After solving the problem, how to get out of the circle? Is it to use other labels to move forward to ensure the continuity of the array, or to set the status flag?
  • The array is linear, how to connect it into a circle?

3. Two alternative implementation methods

method one:

Method: First find the position of the person who should be out of the circle (the person who has registered for m) in each round of counting. After one person goes out of the circle, move the following labels forward in turn, and loop until the last person is left.

Note: the record of each person's original number, the search for the position of the person who left the circle in the array, the movement of the person behind...

The specific code is as follows:

#include <stdio.h>
#define N 100
int main()
{
    
    
   int n,m=3,s=1;//n:总人数,m:报数值,s报数人的起始编号 
   scanf("%d",&n);
   int a[N] = {
    
    0};//数组初始化
   int i,j;
    for(i = 0; i < n; i++)//数组遍历
 {
    
    
      a[i] = i+1; //i是数组的位置量,a[i]是每个人的原始编号(从1开始) 
 }
 i=s-1;   //数组的起点(0) 
 while (n > 1)
   {
    
        
       i = (i+m-1) % n;   //出圈的人在数组中的位置 
     for(j = i+1; j < n; j++)
     {
    
    
         a[j-1] = a[j];
     }
     n--;  //出局1人后,总人数-1 
     if(i == n)  //终点后,开始起点(围成一个圈) 
     {
    
    
         i = 0;
     }
 }
   printf("%d\n", a[i]);//输出留下的人的原始编号 
  
   return 0;
}
Way two:

Method: Set a count count, set count to 0 every time a person leaves the circle, set the count to 0 after the person who leaves the circle each time, and then the next person who leaves the circle will continue to count from 1 ;

Note: Because the total number of people after each person goes out of the circle is -1, in order to prevent the original data n from being destroyed, an x ​​is used instead of n for change. When outputting the original number, just find out who is not 0 in the array~
ps: Method one can also use the counting method to find out the position of the circled person~

The specific code is as follows:

#include <stdio.h>
#define N 50
 
int main()
{
    
    
    int a[N], m, n, x, i, count = 0;
    printf("Please input n m:\n");
    scanf("%d %d", &n, &m);    //输入总人数n和出局要报的数m
 
    x = n;     //把n赋给x,防止使用时n被修改
 
    for (i = 1; i <= n; i++) //数组遍历,此时在数组中的位置就是人原来的编号
    {
    
    
        a[i] = i;
    }
 
    while(x>1)
    {
    
    
     for (i = 1; i <= n; i++) 
        {
    
    
            if (a[i] != 0)      //判断是否出圈,已经出局的就不用报数了
            {
    
    
                count++;        //报数 
            }
            if (count == m) 
            {
    
    
                a[i] = 0;      //出圈的人置为0,而后不参与报数
                count = 0;
                x--;           //出圈一个,总人数减1
            }
        }
    }       //循环结束后,出圈的人都已经被置为0,留下唯一一个人 
    for (i = 1; i <= n; i++)
    if(a[i]!=0)
    printf("%d ",i);    //输出留下的人的原始编号 
    
    return 0;
}

TIP: Joseph problems can also use recursion and list of settlement.

Guess you like

Origin blog.csdn.net/qq_51366851/article/details/113060404