首页 > 其他分享 >约瑟夫环【第九届】【决赛】【C组】

约瑟夫环【第九届】【决赛】【C组】

时间:2024-04-02 21:29:05浏览次数:47  
标签:决赛 第九届 int 圈子 约瑟夫 剩下 编号 淘汰 报数

         n 个人的编号是 1~n,如果他们依编号按顺时针排成一个圆圈,

        从编号是1的人开始顺时针报数。

     (报数是从1报起)当报到 k 的时候,这个人就退出游戏圈。下一个人重新从1开始报数。
  求最后剩下的人的编号。这就是著名的约瑟夫环问题。
  本题目就是已知 n,k 的情况下,求最后剩下的人的编号。
  题目的输入是一行,2个空格分开的整数n, k
  要求输出一个整数,表示最后剩下的人的编号。
  约定:0 < n,k < 1百万
  例如输入:
  10 3
  程序应该输出:
  4

通过一个示例模拟一下:

模拟过程解法:通过模拟报数的过程来逐渐淘汰参与者,直到只剩下一个人为止。

(这种方法在人数较少时是有效的,但对于大规模的输入可能效率不高。)

外圈是编号,内圈是人的代号,初始值是一样的,但当这个人出局后,出局的位置可以标记为0

容易知道,最后一定会剩下一个人。

模拟报数和淘汰过程:外层循环负责一直运行直到只剩下一个人为止。每轮循环中,通过内层循环模拟报数过程,直到报数达到 k。每次报数时,它都会检查当前的编号是否已经被淘汰(即a[j]是否为0)。如果没有被淘汰,就继续报数直到 cnt 达到 k。达到k时,当前报到k的人的编号(即a[j])会被设置为0,表示这个人被淘汰。

寻找最后剩下的人:在淘汰过程完成后,通过最后一个循环遍历a向量来找出最后剩下的人的编号,并输出这个编号。 

#include <bits/stdc++.h>
#define endl '\n'
using namespace std;

int main() {
	int n,k;
	cin>>n>>k;
	vector<int> a(n+1);//存储编号 
	for(int i=1;i<=n;i++){
		a[i]=i;
	}
	int cnt=0,j=0;
	for(int i=1;i<n;i++){//外层循环,每一局都会出去一个人 
		while(cnt<k){
			j++;
			if(j>n)  j=1;//如果超过人数,需要重新重1开始
			if(a[j]!=0) cnt++;
			
		}
		//cout<<a[j]<<" "; 
		a[j]=0;//出局后的处理 
		cnt=0;
	}
	for(int i=1;i<=n;i++){
		if(a[i]!=0) cout<<a[i];
	}
	return 0;
}

 递归解法:

使用约瑟夫问题的数学公式

 对于n个人,报数到k的情况,最后剩下的人的编号f(n, k)可以通过以下递推公式计算:

其中,f(n-1, k) 表示在前一次迭代中最后剩下的人的编号,初始条件是当只有一个人时,这个人的编号是0(根据公式的定义,实际编号应该加1)。我们可以通过这个公式直接计算最后剩下的人的编号。

这个递推公式的美妙之处在于,它将一个复杂的迭代问题转化为了一个可以通过简单递归解决的问题,极大地简化了问题的解法。通过递归地应用这个公式,我们可以高效地找到任意大小的约瑟夫环问题的解。 

对公式的解释如下:

  1. 基本情况:当圆圈中只剩下一个人时,即n=1的情况下,这个人就是最后的胜利者。在这种情况下,胜利者的编号是0(如果我们从0开始编号)。这就是递归的基础情况。

  2. 递归情况:假设我们知道对于n−1个人的情况下,最后的胜利者的编号为f(n−1,k),我们需要计算n个人的情况下最后的胜利者编号。

    • 在n个人中,第一个被淘汰的人的编号是k mod n(因为我们是从1开始数的,如果是从0开始,则是(k−1) mod n。
    • 当这个人被淘汰后,圈中就剩下了n−1个人,而下一个开始报数的人就取代了被淘汰人的位置,成为了新圈子中的第一个人。
    • 此时,问题就变成了一个新的约瑟夫环问题,但规模减小到了n−1个人。如果我们将淘汰的人之后的那个人看作新圈子的起点,那么我们可以假设新圈子是从0开始重新编号的。
  3. 编号转换:重要的一步是如何将新圈子的胜利者编号转换回原来的n个人中的编号。由于新圈子是从被淘汰的人的下一个人开始的,所以原圈子和新圈子的编号有一个固定的偏移量,即k mod n。因此,我们可以用f(n−1,k)+k来表示原圈子中胜利者的位置。但是,因为总人数是n,我们需要取模n来确保编号不会超出范围。

#include <iostream>
// 计算约瑟夫环问题的函数
int josephus(int n, int k) {
    if (n == 1)
        return 0;
    else
        // 递归调用,并应用约瑟夫环问题的解法公式
        return (josephus(n - 1, k) + k) % n;
}

int main() {
    int n, k;
    // 读取n和k的值
    std::cin >> n >> k;
    
    // 计算最后剩下的人的编号
    int result = josephus(n, k) + 1; // 加1是因为编号从1开始
    std::cout << result << std::endl;
    
    return 0;
}

标签:决赛,第九届,int,圈子,约瑟夫,剩下,编号,淘汰,报数
From: https://blog.csdn.net/m0_73504951/article/details/137289288

相关文章

  • 【IEEE出版 | 西安理工大学主办,多高校承办 | EI、SCOPUS双检索 | 计算机领域 ei 会议
    第九届计算机与信息处理技术国际学术会议(ISCIPT2024)将于2024年5月24日-26日在西安召开会议。ISCIPT2024将围绕“计算机与信息处理技术”的新研究领域,为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供一个分享专业经验,扩大专业网络,面对面交流新......
  • 【IEEE会议征稿通知】第九届信息科学、计算机技术与交通运输国际学术会议(ISCTT 2024)
    【IEEE会议】第九届信息科学、计算机技术与交通运输国际学术会议(ISCTT2024)20249th InternationalConferenceonInformationScience,ComputerTechnologyandTransportation   第九届信息科学、计算机技术与交通运输国际学术会议(ISCTT2024)将于2024年6月28-30......
  • 2017天梯赛总决赛:L1-8 矩阵A乘以B
    题目描述给定两个矩阵A和B,要求你计算它们的乘积矩阵AB。需要注意的是,只有规模匹配的矩阵才可以相乘。即若A有Ra​行、Ca​列,B有Rb​行、Cb​列,则只有Ca​与Rb​相等时,两个矩阵才能相乘。输入格式:输入先后给出两个矩阵A和B。对于每个矩阵,首先在一行中给出其行数R和列数C,随后R......
  • 2024年国际地球科学奥林匹克竞赛全球总决赛志愿者招募通知
    第17届国际地球科学奥林匹克竞赛(InternationalEarthScienceOlympiad,IESO)全球总决赛将于2024年8月8日—8月16日在北京举行。本竞赛致力于提高全球地球科学教育水平、提升公众对地球科学的关注度,自2007年开办以来,得到了广泛的认可。本届IESO全球总决赛为自2020年以来首次线......
  • 【公告】第九届元宇宙数字人设计大赛,报名工作现已进入尾声!
    “第九届元宇宙数字人设计大赛”报名工作现已进入尾声。特此公告,本次大赛的报名截止时间为3月31日下午5点。请各位有意向参赛的选手抓紧时间,确保在规定时间内完成报名。图片本次大赛旨在选拔和培养数字领域的优秀人才,为参赛者提供一个展示自我、交流学习的平台。请广大参赛者珍......
  • 约瑟夫环问题
    题目描述约瑟夫环问题:设有n个人围坐一圈,并按顺时针方向1−n编号。从第s个人开始进行报数,报数到第m个人,此人出圈,再从他的下一个人重新开始从1到m的报数进行下去,直到只剩一个人为止。输入人数n;从第s个人开始报数s;报到第几个数m。输出剩下的最后一个人的编号。代码......
  • 洛谷题单指南-线性表-P1996 约瑟夫问题
    原题链接:https://www.luogu.com.cn/problem/P1996题意解读:约瑟夫问题是队列的典型应用。解题思路:n个人围圈报数,可以直接基于数组实现循环队列操作,再定义额外数组记录每个人是否已经出圈即可。更直观的做法,定义队列,初始放入1~n,然后重复n次,每次从1~m报数,如果报数到m,直接出队,......
  • 蓝桥杯2020决赛:试题 I 奇偶覆盖
    原题如果不考虑奇偶性,其实就是扫描线的板子。考虑如何处理奇偶:首先在线段树存两个变量\(len_1\)以及\(len_2\),分别表示奇长度和偶长度。再用\(sum\)记录当前两个端点之间被覆盖了多少次。然而我们无法直接获得每一个子区间的具体覆盖数目。所以从奇偶性的特点方面入手。......
  • P1996 约瑟夫问题
    题目描述nn个人围成一圈,从第一个人开始报数,数到mm的人出列,再由下一个人重新从11开始报数,数到mm的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。注意:本题和《深入浅出-基础篇》上例题的表述稍有不同。书上表述是给出淘汰n−1n−1名小朋友,而该题是全部出......
  • 中央财经大学 &2023 百度之星决赛游记
    榜题解12.29收拾东西的时候发现装不下,强行塞到双肩包+单肩包里了第一次尝试在电脑上下打印订单,然后下去发现机器坏了。。。12.30打印机还是坏的,本来就起得不早。。。去12宿楼底打印的时候还被宿管认出来了,问我是哪个宿舍的,有点震惊7.30出发,8.30到天津站,9.30到北京南......