约瑟夫问题的朴素解法

问题描述:

  数1,2,3......n顺序排列成一个圆环,从第k个数开始顺时针往后数,数到第m个数删掉,如此直到只剩下最后两个数,这两个数是?

 

n:环里总共有n个数

k:从第k个数开始

m:每数到第m个删一个

 

首先声明一个标记数组,每个元素默认值为0,如果被删掉则置为1。

#全局变量
bool a[MAXN];  

同时用p来作标针指向当前的数。

int p = k-1;

然后循环n-2次,因为总共要删掉n-2个数。

for(int i=0;i<n-2;i++){

}

对于n-2次循环的每次内————声明一个变量t用来计数,初始化为0,开一个for(;;)循环,t累加,p也往后推,如果t递增到m时删掉p指向的数,同时进入下次循环。

这里我们采用 p = (p+1)%n 来给p递加。

        int t = 0; 
        for ( ; ; ) {
            if (!a[p]) { 
                t++;
                if (t == m) break;    
            } 
            
            p = (p + 1) % n; 
        }
        a[p] = 1; 
        p = (p + 1) % n; 

 

完整代码:

#include<bits/stdc++.h>
using namespace std;

int k,n,m;
bool a[105];
int main(){
    cin>>n>>k>>m;
    int p=k-1;
    for(int i=0;i<n-2;i++){
        int t=0;
        for(;;){
            if(!a[p]){
                t++;
                if(t==m){break;}

            }
        p=(p+1)%n;    
        }
        a[p]=1;
        p=(p+1)%n;
    }

    for(int i=0;i<n;i++){
        if (!a[i]) printf("%d ", a[i]);
    }
    return 0;
}
posted @ 2019-12-25 13:31  dynmi  阅读(370)  评论(0编辑  收藏  举报