出圈游戏(单链表)

  1. 用链表实现以下功能:有n个人围成一个圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号。

(1)编程提示

每三个人离开,置为0;当数到最后一个人时,将指针重新指向第一个人;m表示离开的人数,当m=n-1时,说明只剩下一个人,循环结束

解题思想:每一个结点代表一个人,起始每一个人都设置个状态标志1,报到号码的人出圈,状态标志改变为0;最后在for 循环遍历找出起始状态标志的人输出。

输入样例:

10

输出样例:

4

代码:

#include<stdio.h>
#include<stdlib.h>

struct Person *output(struct Person *head,int n);
struct Person *creat(int n);
struct Person
{
    int num;//号码 
    int sign;//状态标志 
    struct Person *nxet;
};

int main()
{
    int n;
    struct Person *head;
    
    scanf("%d",&n); 
    head = creat(n);    
    output(head,n); 
    return 0;
}

struct Person *creat(int n)//创建链表 
{
    struct Person *p,*pr,*head;
    int i;
    
    for (i=1; i<=n; i++)
    {
        p=(struct Person *)malloc(sizeof(struct Person));
        p->num=i;
        p->sign=1;    // 起始状态为1 
        
        if (i==1)
            head=pr=p;
        else
        {
            pr->nxet=p;    //前驱结点连接当前结点 
            pr=p;    //连接好以后更新 
        } 
    }
    p->nxet=NULL;//最后一个节点指向NULL 
    
    return head;
}

struct Person * output(struct Person *head,int n)
{
    int k=0;//计数报的次数,叫到3时候对应的人出圈 
    int i=1;
    int m=0;//代表出去的人数,每出去一个人加一 
    struct Person *p;
    
    p = head;
    while(m<n-1)//出去n-1人,留下一个,游戏结束条件 
    {
        if(p->sign == 1)//1代表在这个圈里面,每报一次k加一 
            k++;
            
        if (k==3)//报到3的人出圈 
        {
            p->sign = 0;//状态标志更新为0 
            k = 0;//从新开始报数 
            m++;//出圈的人加一 
        }
        
        i++;
        p = p->nxet;
        
        if (i == n+1)//当报到最后一个号码此时圈里面人数不是1就从新从第一个人开始报,因为出圈的人状态改变,此时上面k计数时不影响 
        {
            i = 1;
            p =head;
        }                    
    }
    
    for (p=head; p!=NULL; p=p->nxet)
    {
        if (p->sign == 1)//检测在圈里面的状态标志输出 
            printf("%d\n",p->num);
    }
}
 
 
  

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

膽小

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值