CCF ——游戏

本文介绍了一个有趣的游戏报数问题,通过编程找出最后获胜者。利用链表和队列两种数据结构实现,展示了不同方法的效率对比。

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

试题编号:201712-2
试题名称:游戏
时间限制:1.0s
内存限制:256.0MB
问题描述:
问题描述
  有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
  游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
  例如,当n=5, k=2时:
  1号小朋友报数1;
  2号小朋友报数2淘汰;
  3号小朋友报数3;
  4号小朋友报数4淘汰;
  5号小朋友报数5;
  1号小朋友报数6淘汰;
  3号小朋友报数7;
  5号小朋友报数8淘汰;
  3号小朋友获胜。

  给定nk,请问最后获胜的小朋友编号为多少?
输入格式
  输入一行,包括两个整数nk,意义如题目所述。
输出格式
  输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
  对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。

#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
    int data;
    struct node *next;
}*LinkList,Lnode;
void TraverseList(LinkList h, int M);
void ListDelete(LinkList h,int M,int k);

int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    LinkList head;
    head = (LinkList)malloc(sizeof(Lnode));
    head->next = NULL;
    int i;
    LinkList p,q;
    q = head;
    for(i=1; i<=n; i++)
    {
        p = (LinkList)malloc(sizeof(Lnode));
        p->data = i;
        q->next =p;
        q = p;
    }
    p->next = head->next;
    //TraverseList(head,n);
    if(k==1)
        printf("%d\n",n);
        else if(n == 1)
            printf("%d\n",1);
    else

        ListDelete(head,n,k);



    return 0;
}
void TraverseList(LinkList h, int M)
{
    int i = 1;
    LinkList p = h->next;
    printf("参与的人的编号为:\n");
    while (i<=M)
    {
        printf("%d\t", p->data);
        p = p->next;
        i++;
    }
    printf("\n");
}

void ListDelete(LinkList h,int M,int k)
{

    int num = 1;
    LinkList p = h,q;
    while(M>1)
    {
        //printf("num == %d\n",num);
        //printf("未更改前:%d\n",p->data);
        if(num%k == 0 ||num%10 ==k)
        {
            q =p->next;
            p ->next = q->next;
            //printf("更改后:%d\n",p->data);
            //printf("淘汰%d号\n",q->data);
            free(q);
            num++;
            M--;
        }

        num++;
        p = p->next;
    }
    //printf("***************获胜者为:%d号***************",p->data);
    printf("%d\n",p->data);
}

以上的代码只得了60分,没能来的及更改,待以后再改

附正确代码:

#include <iostream>
#include <queue>
using namespace std;
int main() {
    int n=0,k=0,i=0,num=1;
    cin>>n>>k;
    queue<int, deque<int> > q; //定义一个队列来保存报数
    for(i=1;i<=n;i++) { //初始化队列
        q.push(i);
    }
    while(q.size()>1) { //判断队列是否只剩下一个元素
        int top = q.front(); //保存当前队首的元素
        q.pop();    //将当前队首元素值从队列中删除
        if(num%k!=0 && num%10!=k) { //判读当前的报数是否满足游戏规则
            q.push(top);    //若满足,则将队首重新插入队尾,等待下一轮游戏
        }
        num++;  //报数+1
    }
    cout<<q.front();    //输出队列q中仅剩的一个元素
    return 0;
}
转载自:http://blog.youkuaiyun.com/Jason_first/article/details/79111163


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值