姜姜(音效),好久不见 今天讲讲418 有N个人围成一圈,编号从1到N 从1号开始报数,数到第m个人就将其淘汰 从下一个人重新开始报数,重复这个过程 直到只剩最后一人 在提到的变种问题中:

总人数是2k(k个好人和k个坏人) 好人编号1到k,坏人编号k+1到2k 需要找到最小的m,使得在第一个好人被杀之前,所有坏人都已被杀 以你给的例子n=6(即k=3)为例:

好人:1,2,3 坏人:4,5,6 当m=5时,死亡顺序是5,4,6,2,3,1 先杀坏人5 然后坏人4 然后坏人6 这时所有坏人都被杀死了,之后才杀好人2 所以m=5满足条件 要验证一个m是否满足条件,我们需要:

模拟整个淘汰过程 检查在第一个好人被杀之前,是否所有坏人都已被杀 找出满足这个条件的最小的m 这个问题需要编写算法来寻找最小的m,因为随着k增大,手动计算会变得非常复杂。通常的解决方法是:

从m=k+1开始尝试(因为m必须大于k才能保证第一轮不杀好人) 对每个m模拟淘汰过程 找到第一个满足条件的m 记得点赞 答案

#include<bits/stdc++.h>
using namespace std;
int main(){
	int a[10000]={0};
	int b;
	
	while(cin>>b)
	{
		if (b==0){
			break;
		}
		int d=2*b;
		int c[10000]={0};
		int e=1;
		for(int i=1;i<=b;i++)
		{
			c[i]=(c[i-1]+e-1)%(d-i+1);
			if(c[i]<b)
			{
				i=0;
				e++;
			}
		}
		a[b]=e;
		cout<<e<<endl;
	}
	return 0;
}

3 条评论

  • 1