2018 Chinese Multi-University Training, Nanjing U Contest
阿新 • • 發佈:2021-07-16
A:Character Encoding
插板法+容斥
https://blog.csdn.net/codeswarrior/article/details/81906367?utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~BlogCommendFromBaidu~default-1.control
講的特別好
int fact[maxn], finv[maxn], inv[maxn]; void init() { fact[0] = fact[1] = finv[0] = finv[1] = inv[0] = inv[1] = 1; for(int i = 2; i < maxn; ++ i) { fact[i] = fact[i - 1] * i % mod; inv[i] = (mod - mod / i) * inv[mod % i] % mod; finv[i] = finv[i - 1] * inv[i] % mod; } } inline int C(int n, int m) { if(n < 0 || m < 0 || m > n) return 0; return fact[n] * finv[m] % mod * finv[n - m] % mod; } inline void qmod(int &a) { while(a >= mod) a -= mod; } signed main() { init(); int t = rd(); while(t--) { int n = rd(), m = rd(), k = rd(); int ans = C(k + m - 1, m - 1); for(int i = 1, f = -1; i * n <= k; ++ i, f = -f) qmod(ans += f * C(k - i * n + m - 1, m - 1) * C(m, i) % mod + mod); printf("%lld\n", ans); } return 0; }
D: Parentheses Matrix
打標找規律的構造題,規模比較大,注意的是剪枝
int ans = 0, n, m, cnt = 0; int c[maxn], r[maxn]; char mp[202][202]; void dfs(int x, int y) { cnt ++; if(cnt % 100000000 == 0) printf("%lld\n", cnt); if(x == n - 1) { int res = 0; for(int i = 0; i < n; ++ i) if(r[i]) res ++; for(int i = 0; i < m; ++ i) if(c[i]) res ++; if(n + m - res < ans) return ; res = 0; for(int i = 0; i < n; ++ i) { int cnt = 0; for(int j = 0; j < m; ++ j) if(mp[i][j] == '(') cnt ++; else if(cnt) cnt --; else {cnt = -1; break;} if(cnt == 0) res ++; } for(int i = 0; i < m; ++ i) { int cnt = 0; for(int j = 0; j < n; ++ j) if(mp[j][i] == '(') cnt ++; else if(cnt) cnt --; else {cnt = -1; break;} if(cnt == 0) res ++; } //if(res == ans) { // for(int i = 0; i < n; ++ i) puts(mp[i]); // dbg(ans); puts(""); //} if(res > ans) { for(int i = 0; i < n; ++ i) { for(int j = 0; j < m; ++j) printf("%c", mp[i][j]); puts(""); } puts(""); ans = res; dbg(ans); } return; } mp[x][y] = '('; r[x] ++; c[y] ++; dfs(x + (y + 1) / m, (y + 1) % m); mp[x][y] = '('; r[x] --; c[y] --; mp[x][y] = ')'; r[x] --; c[y] --; dfs(x + (y + 1) / m, (y + 1) % m); mp[x][y] = ')'; r[x] ++; c[y] ++; } signed main() { int t = rd(); while(t--) { n = rd(), m = rd(); for(int i = 0; i <= n; ++ i) r[i] = 0; r[0] = r[n - 1] = m; for(int i = 0; i <= m; ++ i) c[i] = 0; for(int i = 0; i <= n; ++ i) mp[i][m] = '\0'; //ans = 0; ans = 8; for(int j = 0; j < m; ++ j) mp[0][j] = '(', mp[n - 1][j] = ')'; //dfs(1, 0); //dbg(ans); if(n & m & 1) for(int i = 1; i <= n; ++ i) for(int j = 0; j <= m; ++ j) printf("%c", "(\n"[j == m]); else if(n & 1) for(int i = 1; i <= n; ++ i) {for(int j = 0; j < m; ++ j) printf("%c", "()"[j % 2]); puts("");} else if(m & 1) for(int i = 1; i <= n; ++ i) {for(int j = 0; j < m; ++ j) printf("%c", "()"[i % 2 == 0]); puts("");} else { int x = n, y = m; if(x > y) swap(x, y); for(int j = 0; j < y; ++ j) mp[0][j] = '(', mp[x - 1][j] = ')'; if(x == 4) for(int j = 0; j < y; ++ j) mp[1][j] = "()"[j >= (y >> 1)], mp[2][j] = ")("[j >= (y >> 1)]; else if(x > 4){ for(int i = 1; i < x - 1; ++ i) { if(i & 1) for(int j = 0; j < y; ++ j) mp[i][j] = "()"[j % 2]; else for(int j = 0; j < y; ++ j) mp[i][j] = "()"[(j % 2 == 0 && j != 0) || j == y - 1]; } } if(n > m) for(int i = 0; i < x; ++ i) for(int j = i + 1; j < y; ++ j) swap(mp[i][j], mp[j][i]); for(int i = 0; i < n; ++ i) mp[i][m] = '\0'; for(int i = 0; i < n; ++ i) puts(mp[i]); } } return 0; } /* case: h = 2 ((((( ))))) case: h = 4 (((((( ((())) )))((( )))))) case: h > 6 (((((( ()()() (()()) ()()() (()()) )))))) one case can swap to another case */