约瑟夫环(纯模拟)

本文探讨了一个有趣的问题:在特定规则下,N个人围成一圈报数,报到3的人离开,最终谁将留在圈内。通过代码实现解决此数学问题,深入理解循环和条件判断的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有N个人围成一圈,顺序排号。从第一个人开始报数(1~3报数),报3的人退出圈子,问最后留下的人原来排在第几号?
上代码

#include<iostream>
using namespace std;
int main()
{
    int *p,j,i,n,a[100];
    cin>>n;
    for(i=0;i<n;i++)
      a[i]=i+1;
    p=a;
    for(i=0,j=0;i<n-1;)
    {
       if((*p)!=0) 
        j++;
       if(j==3) 
       {
         i+=1;
         *p=0;
         j=0;
       }
       p++;  
       if(p==(a+n))
       {
         p=a;
         continue;
       }
    }
    for(p=a;p<(a+n);p++)
     if(*p!=0)
      cout<<*p<<endl;
}

如果入门的话,可以研究这个程序,抠出一个模板,不过个人感觉没什么大必要。这是最水的代码……

``` #include<stdio.h> #include<stdlib.h> //数据结点结构:存储每个人的编号和密码 typedef struct data { int id;//人员编号 int password;//密码(用于确定下一轮的报数上限) } Data; //链表结点结构 typedef struct node { Data data; struct node *next; } Node; //创建循环链表 Node* createCircularList(int n) { Node *head=(Node*)malloc(sizeof(Node));//创建头结点 head->next=head;//初始时头结点自己形成环 Node *tail=head;//尾指针用于快速插入 for(int i=1;i<=n;i++) { Node *newNode=(Node*)malloc(sizeof(Node)); printf("请输入第%d号同学的密码:", i); scanf("%d",&newNode->data.password); newNode->data.id=i; //插入新结点到链表尾部 newNode->next=head;//新结点指向头结点形成环 tail->next=newNode; tail=newNode;//更新尾指针 } return head; } //约瑟夫环 void josephus(Node *head,int initialMax) { if(initialMax<=0) { printf("报数上限必须为正整数\n"); return; } Node *current=head->next;//从第一个有效结点开始 Node *prev=head;//记录前驱结点便于删除操作 int currentMax=initialMax; while(current->next!=current) {//当环中还有多个结点时 //找到第currentMax个结点 for(int i=1;i<currentMax;i++) { prev=current; current=current->next; //跳过头结点 if(current==head) { prev=current; current=current->next; } } //处理找到的结点 Data removed=current->data; printf("第 %d 个同学出列\t密码为: %d \n",removed.id,removed.password); //更新下一轮的报数上限并调整链表 currentMax=removed.password; prev->next=current->next; free(current); current=prev->next;//从下一结点重新开始 //跳过头结点 if(current==head) { prev=head; current=current->next; } } //处理最后一个结点 printf("最后的同学为:%d\t密码为:%d\n",current->data.id,current->data.password); free(current); free(head);//释放头结点 } int main() { int total,initialMax; printf("输入总人数:"); scanf("%d",&total); Node *head=createCircularList(total); printf("请输入初始报数上限:"); scanf("%d", &initialMax); josephus(head, initialMax); return 0; }```无法输出最后结果,请改正
最新发布
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值