报数问题(删除后继续报数,不置0)(单向循环链表存储结构模拟此过程)

问题描述:有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号小朋友获胜。
  给定n和k,请问最后获胜的小朋友编号为多少?
输入格式
  输入一行,包括两个整数n和k,意义如题目所述。
输出格式
  输出一行,包含一个整数,表示获胜的小朋友编号。
样例输入
5 2
样例输出
3
样例输入
7 3
样例输出
4
数据规模和约定
对于所有评测用例,1 ≤ n ≤ 1000,1 ≤ k ≤ 9。
要求:利用单向循环链表存储结构模拟此过程。

#include <bits/stdc++.h>

using namespace std;

typedef struct Node {
    int data;//报的数
    int num;//编号
    struct Node* next;
};
typedef struct Node* PNode;

/*-------判断当前节点是否为k的倍数或其末位数(即数的个位)为k-----------------*/
int judge(PNode p,int k)
{
    //求余数
    int yushu;
    yushu=p->data%k;

    //求个位数
    int geweishu=p->data;
    geweishu=geweishu-((geweishu/10)*10);

    if(yushu==0 || geweishu==k)//淘汰条件
        return 1;
    else
        return 0;
}

/*-------游戏准备:创建包含n个结点的循环链表---------*/
PNode createCirLinkedList(int n){
    PNode head=NULL,p=NULL,temp;
    int i;
    for(i=1;i<=n;i++){
    	// 第1个结点
    	if(i==1){
    		temp=(PNode)malloc(sizeof(PNode));
    		head=temp;
    		p=head;
    		temp->data=i;
    		temp->num=i;
    		temp->next=head;
    	}else{
	    	// 以后的结点
			temp=(PNode)malloc(sizeof(PNode));
			temp->data=i;
			temp->num=i;
			temp->next=head;
			p->next=temp;
			p=temp;
	    }
    }
    return head;
}
/*-----------从头结点出发查找结点--------*/
void findElement(PNode head,int k){
	PNode p=head,pre;
	pre->next=p;
	int i=0;
	//从第一个开始寻找节点,如果没不是,就下一个节点,如果找到,就删除它,并且下一个节点编号+1
	while(p->next!=p)
    {
        i++;
        p->data=i;
        if(judge(p,k)==0)//不淘汰
        {
            //printf("不是目标时p的值 %d\n",p->data);
            pre=p;
            p=p->next;
            pre->next=p;
        }
        else//淘汰
        {
            //printf("是目标时p的值 %d\n",p->data);
            PNode t=p;
            pre->next=p->next;
            p=p->next;
            free(t);
        }
    }
    cout<<p->num<<endl;
}
/*-------打印当前循环链表-----------------*/
void printCirLinkedList(PNode head){
    PNode p = head;
    printf("打印[");
    do{
  		printf(" %d ",p->data);
  		p = p->next;
    }while(p != head);
    printf(" %d ",p->data);
    printf("]\n");
}

int main(){
    int n,k,m;
    printf("请输入参与者个数n >>>");
    scanf("%d",&n);
    printf("请输入K >>>");
    scanf("%d",&k);
    PNode head = createCirLinkedList(n);
    //printCirLinkedList(head);
    findElement(head,k);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值