约瑟夫环问题

编号1~n
报数 k 的人死
某一阶段的人数 i
特殊报数 m

思路

先编号n-1来算,再逆推,记得结果都要+1

  • f[1] = 0,
  • f[i] = (f[i-1] + k) % i

变形

  1. 先杀死第m个人,再报数k的人死。
    poj 3517 And Then There Was One
#include <iostream>
using namespace std;
int main()
{
    int n, k, m;
    int ans;
    while(cin >> n >> k >> m && (n || m || k))
    {
        ans = 0;
        for(int i=2; i<=n-1; i++)
            ans = (ans+k)%i;
        ans = (ans + m)%n; //最后换成+m
        cout << ans + 1 << endl;
    }
    return 0;
}
  1. 第1轮,报1的人死,
    第2轮,报2的人死,
    ……
    ……
    第n-1轮,报n-1的人死。
    hdu 5643 King's Game
#include <iostream>
using namespace std;

int main()
{
    int t, n;
    int ans;
    while(cin >> t)
    {
        while(t--)
        {
            cin >> n;
            ans =0;
            for(int i=2, j=n-1; i<=n; i++,j--)
                ans = (ans + j)%i; //换成+j
            cout << ans+1 << endl;
        }
    }
    return 0;
}
  1. 编号1~n,要保留编号为x的人,求k的值(暴力求解)
    ZOJ1088——System Overload
#include <iostream>
using namespace std;
//第一轮第m死,之后为了保留x,求k的最小值
int  joseph(int n, int k)
{
    int ans =0;
    for(int i=2; i<n; i++)
        ans = (ans+k)%i;
    ans = (ans + 1)%n;
    return ans+1;
}

int main()
{
    int n, i;
    while(cin >> n && n)
    {
        for(i=1; ; i++)  //没有限制条件,可以大于n!!!
        {
            if(joseph(n, i) == 2)  //保留第2个
                break;
        }
        cout << i << endl;
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 参考文章 约瑟夫环之二(用递归的思想解决Josephus问题) 解释 解法 初始情况: 0, 1, 2 ........
    Mjolnir1107阅读 4,594评论 0 1
  • 百度百科: 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆...
    KPort阅读 9,316评论 0 4
  • 问题描述:n个人(编号0~(n-1)),从0开始报数,报到(m-1)的退出,剩下的人继续从0开始报数。求胜利者的编...
    xinggang阅读 4,750评论 0 1
  • 好久没有看有关算法的问题了,今天废了不少劲,再感叹一句:要想学好算法就要常练习,没什么捷径可走。废话不多说,如下:...
    时间已静止阅读 11,795评论 0 11
  • 前言 本文编程语言使用Java 问题概述 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕...
    Misery_Dx阅读 5,155评论 1 5

友情链接更多精彩内容