51nod 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>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <vector>
#include <iomanip>
#include <math.h>
#include <map>
using namespace std;
#define FIN     freopen("input.txt","r",stdin);
#define FOUT    freopen("output.txt","w",stdout);
#define INF     0x3f3f3f3f
#define INFLL   0x3f3f3f3f3f3f3f
#define lson    l,m,rt<<1
#define rson    m+1,r,rt<<1|1
typedef long long LL;
typedef pair<int, int> PII;
using namespace std;

/*
F[n] = (F[n - 1] + m) % n, F[1] = 0
返回的下标从0 开始,复杂度大约为O(m)*/
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() {
    //FIN
    int n, k;
    while(~scanf("%d%d", &n, &k)) {
        printf("%d
", Joseph(n, k) + 1);


    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Hyouka/p/7338744.html