美文网首页
(改)~-7 猴子选大王

(改)~-7 猴子选大王

作者: laochonger | 来源:发表于2018-03-19 22:35 被阅读0次

    7-7 猴子选大王(20 分)
    一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?

    输入格式:
    输入在一行中给一个正整数N(≤1000)。

    输出格式:
    在一行中输出当选猴王的编号。

    输入样例:
    11
    输出样例:
    7

    #include<cstdio>
    using namespace std;
    int a[1005];
    void sw(int w, int n){
        for(int i = w; i < n; i++){
            a[i] = a[i+1];
        }
    }
    int main(){
        int N;
        //int t;
        scanf("%d", &N);
        //t = N;
        for(int i = 1; i <= N; i++){
            a[i] = i;
        }
        for(int i = 3; N>1; i = i+2){
            if(i > N) i=i%N;
            
            if(i == 0) i = N;   //这句一开始没加
    
            //printf("(%d,%d,%d) " ,N,i, a[i]); 
            sw(i, N);
            N--;
            //printf("%d",)
        }
        printf("%d", a[1]);
        return 0;
    }
    
    

    这题约瑟夫回环我用的是暴力,直接移动整个数组,然而忘了

     for(int i = 3; N>1;      i = i+2    ){
            if(i > N) i=i%N;
    

    这里的i每次加二,那么最后就有可能碰到i=4 , N=2,i%N=0的情况,(因为i每次只加二,及时地取余使得i%N并不会在其他时刻为0)

    这是一位学长的代码,通过标记,每次从i1开始判断

    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <map>
    #include <set>
    
    using namespace std;
    #define For(i,l,r) for(int (i)=(int)(l);(i)<(int)(r);++(i))
    #define FOR(i,l,r) for(int (i)=(int)(l);(i)<=(int)(r);++(i))
    #define rof(i,l,r) for(int (i)=(int)(l);(i)>=(int)(r);--(i))
    typedef pair<int,int> pii;
    typedef long long ll;
    typedef unsigned long long llu;
    typedef unsigned int ui;
    
    const int mxn=1010;
    bool vis[mxn];
    int main(){
     //   freopen("in.txt","r",stdin);
        int n;scanf("%d",&n);
        int cnt=0,ext=0;
        for(int i=1;i<=n;)if(!vis[i]){
            if(++cnt==3){
                vis[i]=1;++ext;
                cnt=0;
    
            }
            if(++i>n)i=1;//每次都从1开始 
            if(ext==n-1)break;//剩最后一个 
        }else{
            if(++i>n)i=1;//每次从1开始 
        }
    
        FOR(i,1,n)if(!vis[i]){
            printf("%d\n",i);
            break;
        }
        return 0;
    }
    

    也是暴力的方法,然而通过数组标记,就不需要进行数组的移动

    相关文章

      网友评论

          本文标题:(改)~-7 猴子选大王

          本文链接:https://www.haomeiwen.com/subject/grdwfftx.html