Bailian2746 约瑟夫问题

2746:约瑟夫问题
总时间限制: 1000ms 内存限制: 65536kB
描述
约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。
输入
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:
0 0
输出
对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
样例输入
6 2
12 4
8 3
0 0
样例输出
5
1
7

问题链接Bailian2746 约瑟夫问题
问题简述:(略)
问题分析
    约瑟夫问题有2种解法,一是模拟法,二是数学法。
    数学法需要数学推导,这里略去推导过程,只给出程序。
    模拟法可以使用多种数据表示,例如数据结构和STL,这里给出用数组进行模拟的方法。由于逻辑简单,时间上应该更快一些。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C语言程序(模拟法)如下:

/* Bailian2746 约瑟夫问题 */

#include <stdio.h>

#define N 300
int a[N];

int main(void)
{
    int n, k, m, pos, cnt;

    while(scanf("%d%d", &n, &m) != EOF && (n || m)) {
        for( k = 0 ; k < n ; k++ )
            a[k] = k+1;

        for( k = 1, pos = 0; k < n; k++) {
            cnt = 0;
            while( cnt < m ) {
                while( a[pos] == 0 )
                    pos++, pos %= n;
                if(++cnt < m)
                    pos++, pos %= n;
            }
            a[pos] = 0;
            pos++, pos %= n;
        }
        /* 输出结果 */
        for(k = 0; k < n; k++)
            if(a[k]) {
                printf("%d\n", a[k]);
                break;
            }
    }

    return 0;
}

AC的C语言程序(数学法)如下:

/* Bailian2746 约瑟夫问题 */

#include <stdio.h>

int main(void)
{
    int n, m, i, s=0;
    while(scanf("%d%d", &n, &m) != EOF && (n || m)) {
        s=0;
        for (i = 2; i <= n; i++)
            s = (s + m) % i;
        printf ("%d\n", s + 1);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/85522467