首页 > 其他分享 >P1145 约瑟夫

P1145 约瑟夫

时间:2024-01-14 23:55:39浏览次数:27  
标签:int sum ne 约瑟夫 ++ flag P1145 rm

题目链接:

考虑使用循环链表来维护该环形数据结构。但下列代码只能通过70/100

image

#include <bits/stdc++.h>

using namespace std;

int ne[50];
int main()
{
	int k, n, m;
	bool flag = true;
	cin >> k;
	
	n = 2 * k, m = k + 1;
	for (int i = 1; i < n; i++) ne[i] = i + 1;
	ne[n] = 1;
	
	int p = n, t = k;

	for (; ; m++) {
		flag = true;
		p = n, t = k;
		for (int i = 1; i < n; i++) ne[i] = i + 1;
		ne[n] = 1;
		while (t--) {
			for (int i = 1; i < m; i++) p = ne[p];
			
			if (ne[p] >= 1 && ne[p] <= k) {
				flag = false;
				break;
			}
			else ne[p] = ne[ne[p]];
		}

		if (!flag) continue;
		else {
			cout << m;
			return 0;
		}
	}
	return 0;
}

经过思考,当\(\rm m\)的值较大(远远超过剩余总人数)的时候,寻找\(\rm p\)的过程有大量重复。事实上,只需走\(\rm m\)%\(\rm sum\)步(其中\(\rm sum\)为剩余总人数)即可,重复了好几圈。
值得注意的是,当\(\rm m\)%\(\rm sum\)为\(0\)的时候,for循环中的for (int i = 1; i < m%sum; i++)这一步会不执行,且发现规律是删除自己的这个元素。因此需要用到节点的前驱节点。考虑改用双向循环链表维护。

易错点:1、在每次删除完节点之后,要修改某些节点的ne[]和pre[]的值(pre不能忘)
2、m++之后进入到一轮新的循环,链表的结构需要重新定义,指针p的初始指向,sum等变量的值要和初始时一致。

以下是AC代码。

#include <bits/stdc++.h>

using namespace std;

int ne[150], pre[150];

int main()
{
	int k, n, m, sum;
	bool flag = true;
	cin >> k;
	
	n = 2 * k, m = k + 1, sum = 2 * k;
	for (int i = 1; i < n; i++) ne[i] = i + 1;
	ne[n] = 1;
	
	int p = n, t = k;
	
	for (; ; m++) {
		flag = true;
		p = n, t = k, sum = n;
		
		for (int i = 1; i < n; i++) ne[i] = i + 1;
		ne[n] = 1;
		pre[1] = n;
		for (int i = 2; i <= n; i++) pre[i] = i - 1;
		
		while (t--) {
			int y = m % sum;
			if (y == 0) p = pre[p];	
			else for (int i = 1; i < y; i++) p = ne[p];	
			if (ne[p] >= 1 && ne[p] <= k) {
				flag = false;
				break;
			}
			else {
				ne[p] = ne[ne[p]];
				pre[ne[p]] = p;
				sum--;
			}
		}

		if (!flag) continue;
		else {
			cout << m;
			return 0;
		}
	}
	return 0;
}

标签:int,sum,ne,约瑟夫,++,flag,P1145,rm
From: https://www.cnblogs.com/pangyou3s/p/17964480

相关文章

  • 有没有一捏 约瑟夫环
    7-5有没有一捏题目背景一个神秘的数字解码器被用来识别和分析城市监控系统中的加密信号。这些信号用二进制代码表示,二进制值代表了不同类型的安全信息,当二进制值的最后一位为0时,代表该信号是安全的,不会造成网络威胁,如果最后一位是1的,则该信号是1,有潜在的网络威胁。作为一名......
  • 约瑟夫(环形链表)
    约瑟夫(环形链表)/***@author缪广亮*@version1.0*/classJoseph{publicstaticvoidmain(String[]args){CircleSingleLinkedListcircleSingleLinkedList=newCircleSingleLinkedList();circleSingleLinkedList.addBoy(5);circ......
  • 算法:约瑟夫环问题
    问题描述:n个人围成一圈,从编号为k的人开始报数,报到m的人出圈,剩下的人继续从1开始报数,报到m的人出圈;如此往复,求最后一个出圈的人 /**@paramarrarray值为range(1,总人数)*@parammint报号到m的人出圈*@paramcurrentint从第current+1个人开始喊1;值为k-1*@return......
  • 算法题:约瑟夫环问题
    原题:N个人围成一圈顺序编号,从1号开始按1、2、3…顺序报数,报p者退出圈外,其余的人再从1、2、3开始报数,报p的人再退出圈外,以此类推。请按退出顺序输出每个退出人的原序号。输入格式:输入只有一行,包括一个整数N(1<=N<=3000)及一个整数p(1<=p<=5000)。输出格式:按退出顺序输出每个......
  • 大二算法实验一用循环链表解决约瑟夫环
    题目约瑟夫(Joeph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的......
  • 约瑟夫环问题
    我今天要讲的问题是约瑟夫环问题。本蒟蒻第一篇学术文章,多多支持,写的不好请见谅。洛谷题库约瑟夫环问题这题是一道好题目,我这里推荐两种解法1.直接模拟我用了一个数组来模拟,在圈内为无穷大,不在圈内则为0。模拟时要注意以下几点:如果当前已经出了圈,那么这个位置不算一人。......
  • 【十分钟一个知识点】约瑟夫环问题
    问题来历据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,......
  • 约瑟夫问题及深入
    问题大意:从围成标有记号\(1\)到\(n\)个人开始,每隔一个删去一个人,直到最后只有一个人幸存下来。例如\(n=10\)的起始图形:删除的顺序是:\(2,4,6,8,10,3,7,1,9\),最后\(5\)幸存下来。解决:我们设对于有\(n\)个人的环,最终幸存者编号为\(F_n\)。所以\(F_{10}=5\)。接着......
  • 谈谈约瑟夫环的问题
    约瑟夫环问题是一个经典的数学问题,名称来源于传说中的约瑟夫(Josephus)。这个问题描述了一个古老的故事,据说在罗马人占领乔塔帕特后,39个犹太人和约瑟夫及他的朋友们决定用自杀的方式来避免落入罗马人的手中。他们站成一个圆圈,从一个人开始,每次由站在这个人后面的人报数,报数到第m......
  • 用单链表解决约瑟夫问题 C语言实现
    编号为1,2,3,…,n的n个人按顺序针方向围坐一张圆桌旁,每个人手中持有一个密码(正整数)。首先输入一个正整数作为报数上限值m,然后,从第一个人开始按顺序针方向自1开始顺序报数,报到m的人离开桌子,并将他手中的密码作为新的m值,从顺序针方向的下一个就坐在桌旁的人开始重新从1报数,如此下去,直......