Le problème classique de l'implémentation du langage problem_C de Joseph

<Question de Joseph>

1. Brève description du problème

Le problème de Joseph est également appelé anneau de Joseph, qui est un problème d'application mathématique.

On sait qu'il y a n personnes (respectivement numérotées 1, 2, 3 ... n) assises en cercle, à partir de la première personne à déclarer le nombre, et le nombre de personnes qui se rapportent au nombre m sort de le cercle; puis recommencez à partir de la personne suivante pour signaler à nouveau et signaler La personne avec m sort du cercle; le jeu se termine lorsque la dernière personne est laissée. Sortez le numéro d'origine de la personne restante.

2. Réflexion sur les questions

Le problème que nous voulons résoudre:

  • La personne qui rapporte à m est hors du cercle, comment indiquer qu'elle est hors du cercle?
  • Après avoir résolu le problème, comment sortir du cercle? S'agit-il d'utiliser d'autres étiquettes pour avancer pour assurer la continuité de la baie, ou pour définir l'indicateur d'état?
  • Le tableau est linéaire, comment le connecter en cercle?

3. Deux méthodes de mise en œuvre alternatives

première méthode:

Méthode: trouvez d'abord la position de la personne qui devrait être hors du cercle (la personne qui s'est inscrite pour m) à chaque tour de comptage. Une fois qu'une personne est sortie du cercle, déplacez les étiquettes suivantes vers l'avant à tour de rôle et bouclez jusqu'à ce que la dernière personne soit laissée.

Remarque: l'enregistrement du numéro d'origine de chaque personne, la recherche de la position de la personne qui a quitté le cercle dans le tableau, le mouvement de la personne derrière ...

Le code spécifique est le suivant:

#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;
}
Deuxième voie:

Méthode: définissez un décompte, réglez le décompte sur 0 chaque fois qu'une personne quitte le cercle, réglez le décompte sur 0 après la personne qui quitte le cercle à chaque fois, puis la prochaine personne qui quitte le cercle continuera à compter à partir de 1 ;

Remarque: Étant donné que le nombre total de personnes après que chaque personne est sortie du cercle est de -1, afin d'éviter que les données d'origine n soient détruites, un x est utilisé au lieu de n pour le changement. Lors de la sortie du nombre d'origine, il suffit de savoir qui n'est pas 0 dans le tableau ~
ps: La méthode 1 peut également utiliser la méthode de comptage pour trouver la position de la personne encerclée ~

Le code spécifique est le suivant:

#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;
}

CONSEIL: Les problèmes Joseph peuvent également utiliser la récursivité et la liste de règlement.

Je suppose que tu aimes

Origine blog.csdn.net/qq_51366851/article/details/113060404
conseillé
Classement