ccf171202-游戏

题目

问题描述

  有 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。

思路

 这个题目的坑点在于一定要记得考虑k=1的情况,我第一次提交就没有考虑k=1,然后提示运行超时90分。我唯一想到的原因就是for循环太多了或者使用最基本的数组,数据处理显得会很复杂?解决办法大概就是缩减for循环,再不行就只能更改成vector或者queue了。(毕竟测试样例和自己试了几个例子都没问题,所以一定一定要记得考虑边界情况鸭!)后来百度一下,刚好碰到有个同学也是一样的问题导致运行超时90分,也给出了提示(https://blog.csdn.net/zhaoshuling1109/article/details/81232297),感谢!而且这位同学也给出了除基本数组外的别的解法,这里就不搬运啦。就只给出自己最渣渣的解法。

题解

#include<iostream>
using namespace std;

int main(){
    int n,k;
    scanf("%d %d",&n,&k);
    int child[n];
    int num=n;//剩余人数 
    int cur=1;
    for(int i=1;i<n+1;i++){//初始化为顺序编号 
        child[i]=i;
    }
    if(k==1){
        printf("%d",n);
    }
    else{
        while(num!=1){
            for(int i=1;i<n+1;i++){
                //printf("1----child[%d]=%d;\n",i,child[i]);
                if(child[i]!=0){
                    /*if((child[i]%k==0) || (child[i]%10==k)){//如果报到相应数字,小朋友淘汰,则置零 
                        printf("2----child[%d]=0;\n",i);
                        child[i]=0;
                        num--;
                    }
                    else{
                        child[i]=cur;
                        printf("3----child[%d]=%d;\n",i,cur);
                        if((child[i]%k==0) || (child[i]%10==k)){//如果报到相应数字,小朋友淘汰,则置零 
                            printf("4----child[%d]=0;\n",i);
                            child[i]=0;
                            num--;
                        }                    
                    }*/
                    child[i]=cur;
                    //printf("3----child[%d]=%d;\n",i,cur);
                    if((child[i]%k==0) || (child[i]%10==k)){//如果报到相应数字,小朋友淘汰,则置零 
                        //printf("4----child[%d]=0;\n",i);
                        child[i]=0;
                        num--;
                    }                
                    cur++;
                }
                if(num==1){
                    break;
                }            
            }    
        }
        for(int i=1;i<n+1;i++){
            if(child[i]!=0){
                printf("%d",i);
            }
        }        
    }


    return 0;
} 

 忍不住再给出一个我觉得非常好的解法,以及基本要忘了数据结构的我想到却实现不到的做法。参考了这位同学的做法(https://blog.csdn.net/qq_16234613/article/details/79006514)

#include<iostream>
#include<queue>
using namespace std;

int main(){
    int n,k;
    int num=1;
    scanf("%d %d",&n,&k);
    queue<int> list;
    
    for(int i=1;i<n+1;i++){
        list.push(i);
    }
    
    while(list.size()>1){
        int top=list.front();
        list.pop();
        if((num%k!=0) && ((num%10)!=k)){
            list.push(top);
        }
        num++;
    }
    printf("%d",list.front());
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lyeeer/p/11461445.html