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; }
代码其实很短很简单
所以要认真理解约瑟夫问题的核心!