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...