[CSP]201712-2 遊戲 暴力+(以此為例)約瑟夫環的遞推
阿新 • • 發佈:2019-01-09
愚蠢的看錯題了。中文讀題能力還不如英文,有待提升。
所以這道題用普通的陣列模擬操作就可以了。總之跟暴力模擬的約瑟夫環沒什麼區別。
可以用next陣列模擬指標做資料結構,但是資料範圍不大的情況下不建議這麼寫,維護一個指標環寫起來還是比較麻煩的。
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAXN = 1005; bool survive[MAXN]; int solve(int n, int k) { for(int i = 0; i < n; i++) { survive[i] = true; } int cnt = 0, snum = n; int idx = -1; while(snum) { idx = (idx + 1) % n; if(survive[idx] == true){ cnt++; if(cnt % k == 0 || cnt % 10 == k){ survive[idx] = false; //printf("%d\n", idx+1); snum--; } } if(snum == 1)break; } for(int i = 0; i < n; i++)if(survive[i] == true)return i; } int main() { int n, k; scanf("%d%d", &n, &k); int ans = solve(n, k); printf("%d\n", ans+1); return 0; }
但是突然想到比得十分GG的藍橋杯國賽,必須要記錄一下約瑟夫環的標準數學(找規律)解法。
將k固定,設解ANS[n,k] = ans(n)
具有m個數的m約瑟夫環中,刪除一個數之後,相當於重新標號後的m-1約瑟夫環問題。
設從a(1)開始的m約瑟夫環答案為ans(m) = s,在m+1約瑟夫環中,由於經歷了重新標號,m中的標號a(i)應該為a((k+i)%(m+1)) ,所以答案下標也要從s移動到(s+k)%(m+1).
公式:ans(1) = 1, ans(m+1) = (ans(m)+k)%(m+1)。程式碼如下:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; //標準約瑟夫環,非此題題解 int main() { int n, k; int i, s = 0; scanf("%d%d", &n, &k); for (i = 2; i <= n; i++) { s = (s + k) % i; //printf("%d\n",s+1); } printf ("%d\n", s+1); }