[ACM Steps] Joseph 约瑟夫环问题

http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2&sectionid=2&problemid=2

题意:有2k个人,前k个是好人,后K个是坏人。每次干掉一个,要求全部坏人被干掉前不能有好人被干。

人员按0…… 2k-1的顺序编号,方便计算。

本题可简单地把人员编号分成两类,0……k-1为好人,若得出此范围内的编号,则好人被杀,不符合要求,进行下一轮迭代。

若编号为k……2k-1,则坏人被杀,总人数减1,。因为坏人都是一样的,此时可以将编号为最后一个的坏人替代本轮被杀的坏人。

于是坏人的编号为k……sum-1.

(j + m – 1)% sum == 0对应于第一个人。

需要减1的原因在于,上一轮该编号的人已死,本轮该编号的人为另外的坏人,所以减1指向前一个人,一个上一轮已经数过的人。

#include <stdio.h>

int res[15];

int fun(int k)
{
	int sum;
	int m;
	bool flag;
	if(res[k])
		return res[k];
	for(m = k + 1; ;m++)	//m不可能小于k
	{
		sum = 2 * k;
		int j = 0;
		while(1)
		{
			j = (j + m - 1) % sum;	
			sum--;
			if(j < k)	//编号小于k说明是好人
			{
				flag = false;
				break;
			}
			if(sum == k)	//sum等于k说明只剩好人
			{
				flag = true;
				break;
			}
		}
		if(flag == true)
		{
			res[k] = m;
			return res[k];
		}
	}

}

int main()
{
	int k;
	while(scanf("%d",&k) != EOF && k)
	{
		printf("%d\n", fun(k));
	}
	return 0;
}

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/grady1234/article/details/41253119
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞