約瑟夫環 n, k 第 m 個出圈

2021-09-26 23:43:08 字數 1091 閱讀 5838

acm-icpc 2018 瀋陽賽區現場賽 k. let the flames begin (約瑟夫環問題)

題意:有 n 個人圍成乙個圈,從 1 開始報到第 k 個人出環,問第 m 個出環的人是誰,n、m、k <= 1e18 且 min(m,k)<= 2e6。

題解:容易得出o(m)的遞推公式 f[n][m] = (f[n-1][m-1] + k - 1)% n + 1,初始狀態 f[n-m+1][1]容易得出,當 m 小的時候用該公式計算。考慮 k 大 m 小的情況下,遞推式的取膜很多情況下沒有用到,可以用乘法代替加法加速遞推的過程:

當前狀態為f[a][b] = c, 經過 x 次加法後的狀態為 f[a+x][b+x] = c + k * x,假設經過 x 次加法之後需要取模,有

c + k * x > a + x   →   x > (a - c)/ (k - 1)   

得到該不等式後便可以計算出另一種情況了,還要注意 k = 1 需要特判。

#include using namespace std;

#define ll long long

#define ull unsigned long long

#define mst(a,b) memset((a),(b),sizeof(a))

#define mp(a,b) make_pair(a,b)

#define pi acos(-1)

#define pii pair#define pb push_back

const int inf = 0x3f3f3f3f;

const double eps = 1e-6;

const int maxn = 2e6 + 10;

const int maxm = 1e8 + 10;

const ll mod = 1e9 + 7;

ll f[maxn];

int main() else

c += (m - b) * k;

c %= n;

if(c == 0) c = n;

printf("%lld\n",c);}}

}return 0;

}

問題 1160 出圈 (約瑟夫環)

時間限制 1sec 記憶體限制 128mb 提交 1209 解決 426 題目描述 設有n個人圍坐一圈並按順時針方向從1到n編號,從第1個人開始進行1到m的報數,報數到第個m人,此人出圈,再從他的下乙個人重新開始1到m的報數,如此進行下去直到所剩下一人為止。輸入 輸入多行,每行 個數,分別表示n和m...

華為機試 約瑟夫環換m值

問題描述 輸入乙個由隨機數組成的數列 數列中每個數均是大於0的整數,長度已知 和初始計數值m。從數列首位置開始計數,計數到m後,將數列該位置數值替換計數值m,並將數列該位置數值出列,然後從下一位置從新開始計數,直到數列所有數值出列為止。如果計數到達數列尾段,則返回數列首位置繼續計數。請程式設計實現上...

新第k人 約瑟夫環問題

description tt在跟朋友一起做遊戲,tt特別喜歡233這個數字,他把遊戲修改為第233人。即報出233的人要退出遊戲。由於第233人太好玩了,玩的人越來越多,現在你還會知道誰會勝出嗎?input t t組,t 10000 t行,每行乙個數字n代表當前有n個小朋友 n 10000 outp...