求解约瑟夫问题p--什么意思


#include<stdio.h>
void main()
{int a[100];
int *p=a;
int i,k=0,n,m=0;
scanf("%d",&n);
for(i=0;i<n;i++)
*(p+i)=i+1;
for(;m<n-1;p++)
{if(*p!=0) k++;
if(k==3)
    {*p=0;k=0;m++;}
if(p==a+n-1){p=&a[0];p--;}
}
p=a;
while(*p==0) p++;
printf("%d is left\n",*p);
}

这段代码实现的是约瑟夫问题,其中 p 并没有特殊含义。

该程序的基本思路是:将 n 个人的编号存储在数组 a 中,从第一个人开始计数,并按照约定的规则淘汰每个第 m 个人,直到只剩下最后一个人为止。具体过程如下:

使用指针 p 指向数组 a 的首位,即指向第一个人。

循环遍历整个数组,当第 k 个未被淘汰的人报数时,将其淘汰(即将其对应的数组元素设为 0),并计数器 m 加一,记录已经淘汰的人数。

如果已经到达数组 a 的末尾,则将指针 p 重置为数组 a 的首位。

最终,只剩下一个人未被淘汰,输出该人的编号即可。

需要注意的是,在本程序中,数组 a 的第一个元素不使用。因此,如果输入 n=5,表示一共有 5 个人,他们的编号分别为 1、2、3、4 和 5,而不是 0、1、2、3 和 4。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/363421
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:将整数序列循环左移p个位置
  • 除此之外, 这篇博客: 单片机原理及应用复习中的 P 奇偶标志位 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 在这里插入图片描述
    奇偶校验用吧可能

    这个计算还挺容易出的,多看看

    在这里插入图片描述

  • 以下回答由chatgpt基于相关博客总结生成:

    p在约瑟夫问题中是指向字符串中字母的指针,在处理过程中,先用一个指针数组,将指针p指向字符串最开始的''号,再通过逐个读取字符串中非''号的字母,使用一个for循环,用另外一个变量i记录下标,并用指针数组中的另一个指针变量再次指向读到的字母,这样p就指向了字符串中字母。处理完最后一个字母时,把指针后移,指向字符串结束的''号,将这个指针也记录到指针数组,处理完后指针数组中就保存了所有指向非''号的指针变量。最后输出指针数组中所有指向字符的指针指向的字符,即可输出去星号后的字符串。需注意C中字符数组可以直接输出,不一定要用指针;scanf读取完输入字符数组时自动添加了结束符'\0'。

    //去掉字符串中字母之间的星号
    #include <stdio.h>
    #include <string.h>
    
    int main(int argc, char const *argv[]) {
      char s[100] = "\0";
      char *p[100];
      int i = 0, l, end;
      scanf("%s", s);
      while (s[i] == '*') {
        p[i] = &s[i];
        i++;
      }/*指向字符串最开始的'*'号*/
      for (int j = i; j < strlen(s); j++) {
        if(s[j] != '*') {
          p[i++] = &s[j];/*读取字符串中字母*/
          end = j;/*记录最后一个字母位置*/
        }
      }
      for (int j = end + 1; j < strlen(s); j ++) {
        p[i++] = &s[j];/*指向字符串结束的'*'号*/
      }
      for (int j = 0; j < i; j++) {
        printf("%c", *p[j]);
      }
      return 0;
    }