数据结构与算法设计 : 约瑟夫问题

1.约瑟夫问题


欢迎来到新学期,这可能是你们面对的第一个题目哟!加油


前言

这是题目:

约瑟夫问题是一个经典的问题。已知 n 个人(不妨分别以编号 1,2 ,3,…,n 代表 )围坐在一张圆桌周围,从编号为 k 的人开始,从1开始顺时针报数 1, 2, 3, …,顺时针数到m 的那个人,出列并输出。然后从出列的下一个人开始,从1开始继续顺时针报数,数到 m的那个人,出列并输出,…依此重复下去,直到圆桌周围的人全部出列。
输入:n, k, m

输出:按照出列的顺序依次输出出列人的编号,编号中间相隔一个空格,每10个编号为一行。

非法输入的对应输出如下:

a)

输入:n、k、m任一个小于1
输出: n,m,k must bigger than 0.

b)

输入:k>n

输出: k should not bigger than n.

例:

输入:9,3,2

输出:4 6 8 1 3 7 2 9 5


提示:以下是本篇文章正文内容,下面案例可供参考

一、怎么分析?

网上有好多版本,有算公式的,有链表的,我这个也差不多是链表,不过是静态链表,就是数组模拟。思路其实是模拟,轮到第k个就跳出去 ,即ne[k] = ne[ne[k]];
ne[i] 数组代表的是模拟指针,ne[1] = 2 因为1 的下一个就是 2, 当然 ne[n] = 1;因为围成了一个圈。模拟到剩下最后一个人就结束了,Accept!

二、AC代码

1.

代码如下:

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1000010;
int ne[N];

int main()
{
    int n, k, m;
    scanf("%d%*c%d%*c%d", &n, &k, &m);
    if(n < 1 || k < 1 || m < 1) 
    {
        cout << "n,m,k must bigger than 0." << endl;
        return 0;
    }
    if(k > n)
    {
        cout << "k should not bigger than n." << endl;
        return 0;
    }
    for(int i = 1; i < n; i++) ne[i] = i + 1;
    ne[n] = 1;
        
    //初始位置
    k--;
    if(k == 0) k = n;
    int cnt = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m - 1; j++) k = ne[k];
        if(i == n - 1) cout << ne[k] << endl;
        else
        {
            if(cnt % 9 == 0 && cnt != 0) 
            {
                cout << ne[k] << endl;
                cnt = 0;
            }
            else 
            {
                cout << ne[k] << ' ';
                cnt++;
            }
        }
        ne[k] = ne[ne[k]];
    }
    return 0;
}

总结

报错了两次,原因是什么呢?嘻嘻嘻嘻,不知道你们看到没有,每十个一行,我都放一行了,检查了半天。这就是审题的含金量。

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值