約瑟夫環筆記+加速優化板子(HDU3089)

今天看到一題和約瑟夫環相關的問題,就把約瑟夫環的板子整了一下。

問題描述:n個人圍成圈做,編號從0開始到n-1,從第0個人開始報數(從1開始),每次報到m的人出局,然後從後一個人開始繼續往後報數。問最後獲勝的人是誰。

思路:如果下標從0開始,則第一輪m-1被刪除。剩下的數就又生成了一個大小爲n-1的約瑟夫環。其中對應關係(舊–新)

k—-0
k+1—-1
k+2—-2
……
n-1—-n-k-1
0—-n-k
1—-n-k+1
……
k-3—-n-3
k-2—-n-2

如果說f(n) 是n個數的約瑟夫問題的答案

那麼可以得到遞推式子

f(n)=(f(n1)+m)modn

到此,我們已經有了一個O(n) 的求法了。一下是板子

long long Josephus(long long n, long long m, long long start = 0) {
    long long ans = 0;
    for(long long i = 2; i <= n; i++) {
        ans = (ans + m) % i;
    }
    return (ans + start) % n;
}

但是問題來了,如果n很大呢,如hdu3089,其中n爲10的12次,但是m很小隻有1000。

分析:當每次加m的時候其實很多時候ans+m並沒有比i大,所以這裏可以一次性加好多次,但是每次的i不一樣,但是滿足
ans+km<i+k1=>k(m1)<ians1

然後判斷一下就好了,上代碼,要注意題目中的下標

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<time.h>
#include<set>
#include<stack>
#include<vector>
#include<map>

#define pi acos(-1)
#define maxn 111111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8

#define pb push_back

#define mem(a) memset(a,0,sizeof a)

using namespace std;

const long long mod = 1000000007;
/**lyc**/

void init(void) {

}
/**0到n-1下標**/
long long Josephus(long long n, long long m, long long start = 0) {
    if(m == 1) {
        return (start + n - 1) % n;
    }
    long long ans = 0;
    for(long long i = 2; i <= n;) {
        if(ans + m < i) {
            long long step;  ///判斷步數
            if((i - ans - 1) % (m - 1) == 0) step = (i - ans - 1) / (m - 1) - 1;  ///如果能整除
            else step = (i - ans - 1) / (m - 1);  ///如果不能整除
            if(i + step > n) return ((ans + (n - i + 1) * m) + start) % n; ///若果迭代次數夠了
            i += step;
            ans += step * m;
        }
        else {
            ans = (ans + m) % i; ///正常的迭代
            i++;
        }
    }
    return (ans + start) % n;
}
int main() {
    init();
    long long n, k;
    while(scanf("%lld%lld", &n,&k) != EOF) {
        long long ans = Josephus(n, k);
        printf("%lld\n", ans + 1);
    }
    return 0;
}








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章