您的位置:首页 > 其它

51nod 1073 约瑟夫环

2017-09-26 20:52 357 查看
1073 约瑟夫环


基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题


 收藏


 关注

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


上模板,结果记得加1!!!

#include <iostream>

using namespace std;
typedef long long LL;
int Joseph(int n, int m) {
if(n == 1) return 0;
if(m == 1) return n - 1;
LL pre = 0; int now = 2;
while(now <= n) {
if(pre + m >= now) {
pre = (pre + m) % now;
now++;
} else {
int a = now - 1 - pre, b = m - 1;
int k = a / b + (a % b != 0);
if(now + k > n + 1) k = n + 1 - now;
pre = (pre + (LL)m * k) % (now + k - 1);
now += k;
}
}
return pre;
}
int main()
{
int n,k;
int ans=0;
scanf("%d%d",&n,&k);
printf("%d\n",Joseph(n,k)+1);
return 0;
}


函数图像法

/*
* n 个人数到 k 出列,最后剩下的人编号
*/
unsigned long long n, k;

int main()
{
cin >> n >> k;

long long y = k % 2;
long long x = 2, t = 0;
long long z1 = y, z2 = x;
while (x <= n)
{
z1 = y;
z2 = x;
t = (x - y) / (k - 1);
if (t == 0)
{
t++;
}
y = y + t * k - ((y + t * k) / (x + t)) * (x + t);
x += t;
}

cout << (z1 + (n - z2) * k) % n + 1 << endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: