N个人坐成一个圆环(编号为1 - N),从第1个人开始报数,数到K的人出列,后面的人重新从1开始报数。问最后剩下的人的编号。
例如:N = 3,K = 2。2号先出列,然后是1号,最后剩下的是3号。
Input
2个数N和K,表示N个人,数到K出列。(2 <= N, K <= 10^6)
Output
最后剩下的人的编号
Input示例
3 2
Output示例
3
先是自己模拟了一遍
样例和自己出的例子都能过
但是提交结果是 Time Limit Exceed
放一下 TLE的代码
#include <stdio.h>
#include <iostream>
using namespace std;
int a[100005];
int main()
{
int n,x;
while (~scanf("%d%d",&n,&x))
{
for (int i=0; i<n; i++)
a[i]=i+1;
int sum=n;
int start=0,count=1;
while(sum)
{
if(count==x)//报数为x的人离开 所以数组要向前移动一个位置
{
if (sum==1)//判断是否为最后一个人
printf("%d\n",a[start]);
for(int i=start; i<n; i++)//数组向前移动
a[i]=a[i+1];
sum--;
count=1;
}
else
{
count++;//依次报数
start++;
start%=sum;//当start大于sum时 需重新从1,2,3开始
}
}
}
return 0;
}
所以这是一道数学题……
数学题(数论)
看了别人的题解不是很懂 所以这题想了很久
参考:https://www.cnblogs.com/geloutingyu/p/6202200.html
可能是我写题解写得最认真的一次了(毕竟手写(逃
【字丑勿怪】

结合图片理解吧~
后来发现少写了一点 即f(x)的值
f(1)=0
f(2)=0
f(3)=2
f(4)=0
f(5)=2
f(6)=4
f(7)=6
f(x)代表着最后剩下的人的编号在第 n-x+1 轮的编号理解为主 现在放一下代码
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int f=0;
for(int i=2; i<=n; ++i)
f=(f+m)%i;
printf("%d\n", f+1);
return 0;
}
代码其实很短很简单
所以要认真理解约瑟夫问题的核心!
本文探讨约瑟夫环问题的高效求解方法,通过分析传统遍历算法的时间复杂度瓶颈,提出一种数学方法实现快速求解。文章详细介绍了如何通过递推公式找到最后一个幸存者的编号,并附带代码实现。
8601

被折叠的 条评论
为什么被折叠?



