洛谷 P2348 題解
阿新 • • 發佈:2020-10-27
本題解同步於我的洛谷部落格
本題思路:模擬。
首先我們容易發現,因為每位玩家至少需要 \(4\) 張牌,所以如果 \(k < n \times4\),那麼輸出無解。
然後我們可以看出,這道題的主要部分是在洗牌上。
於是我們觀察洗牌後的順序:
b[1] = a[k / 2 + 1];
b[2] = a[1];
b[3] = a[k / 2 + 2];
b[4] = a[2];
...
b[k - 1] = a[k];
b[k] = a[k / 2];
//其中 b 為洗牌後牌的花色,a 為洗牌前牌的花色
可以看出(其中 a 為洗牌前牌的花色,b 為洗牌後牌的花色):
\[b_i = a_{\frac{k}{2} + \lceil {\frac{i}{2}} \rceil} (i \ \bmod 2 == 1) \]所以,我們就可以模擬 \(m\) 次洗牌,然後再 \(O(k)\) 發牌。
時間複雜度為 \(O(mk)\)。
AC 程式碼:
#include <iostream> #include <cstdlib> #include <string> #include <cstdio> using namespace std; int n, k, m, p; struct sgs { string a, b; } c[100010], d[100010]; int main() { cin >> n >> k >> m >> p; if(k < n * 4) puts("Error:cards not enough"), exit(0); //判斷無解情況 for(int i = 1; i <= k; i ++) cin >> c[i].a >> c[i].b; for(int i = 1; i <= m; i ++) { for(int j = 2; j <= k; j += 2) { //模擬洗牌過程 d[j].a = c[j / 2].a; d[j].b = c[j / 2].b; d[j - 1].a = c[k / 2 + j / 2].a; d[j - 1].b = c[k / 2 + j / 2].b; } for(int j = 1; j <= k; j ++) c[j] = d[j]; //每次洗完牌要更新原陣列 } for(int i = 1, tot = 0; i <= k, tot < 4; i ++) { //模擬出牌過程 if((i - 1) % n + 1 == p) { cout << d[i].a << ' ' << d[i].b << endl; ++ tot; } } return 0; }