CodeCraft-19 and Codeforces Round #537 (Div. 2)
Posted dup4
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeCraft-19 and Codeforces Round #537 (Div. 2)相关的知识,希望对你有一定的参考价值。
A. Superhero Transformation
签
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 char s[N], t[N], Hash[N]; 6 7 bool ok() 8 { 9 int n = strlen(s + 1); 10 for (int i = 1; i <= n; ++i) 11 if (Hash[s[i]] != Hash[t[i]]) 12 return false; 13 return true; 14 } 15 16 int main() 17 { 18 memset(Hash, 0, sizeof Hash); 19 Hash[‘a‘] = 1; 20 Hash[‘e‘] = 1; 21 Hash[‘i‘] = 1; 22 Hash[‘o‘] = 1; 23 Hash[‘u‘] = 1; 24 while (scanf("%s%s", s + 1, t + 1) != EOF) 25 { 26 int len1 = strlen(s + 1), len2 = strlen(t + 1); 27 if (len1 != len2) puts("No"); 28 else 29 puts(ok() ? "Yes" : "No"); 30 } 31 return 0; 32 }
B. Average Superhero Gang Power
Hacked.
注意如果最大值不止一个,那么去掉几个是不一定的
枚举即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 100010 6 int n, k, m; 7 ll a[N]; 8 9 int main() 10 { 11 while (scanf("%d%d%d", &n, &k, &m) != EOF) 12 { 13 for (int i = 1; i <= n; ++i) scanf("%lld", a + i); 14 sort(a + 1, a + 1 + n); 15 for (int i = 1; i <= n; ++i) a[i] += a[i - 1]; 16 double res = a[n] * 1.0 / n; 17 for (int i = 0; i < n; ++i) 18 { 19 if (m < i) break; 20 ll add = min(1ll * (m - i), 1ll * k * (n - i)); 21 res = max(res, (a[n] - a[i] + add) * 1.0 / (n - i)); 22 } 23 printf("%.10f ", res); 24 } 25 return 0; 26 }
C. Creative Snap
递归求解即可,注意一整段空直接返回$A$
这样最多只有$k个长度为1的节点被访问到$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 6 int n, k, A, B; 7 vector <int> v; 8 9 ll CDQ(ll l, ll r) 10 { 11 if (r < l) return 0; 12 int num = upper_bound(v.begin(), v.end(), r) - lower_bound(v.begin(), v.end(), l); 13 if (num == 0) return A; 14 ll tmp = 1ll * (r - l + 1) * B * num; 15 if (l == r) return tmp; 16 ll mid = (l + r) >> 1; 17 return min(tmp, CDQ(l, mid) + CDQ(mid + 1, r)); 18 } 19 20 int main() 21 { 22 while (scanf("%d%d%d%d", &n, &k, &A, &B) != EOF) 23 { 24 v.clear(); 25 for (int i = 1, x; i <= k; ++i) 26 { 27 scanf("%d", &x); 28 v.push_back(x); 29 } 30 sort(v.begin(), v.end()); 31 printf("%lld ", CDQ(1, 1 << n)); 32 } 33 return 0; 34 }
D. Destroy the Colony
Solved.
题意:
有$n个人,n为偶数, 每个人有一个种类$
$询问给出x, y 要求将和第x人同种类并且和第y个人同种类的人放在一个集合$
$并且挑选出一些人和他们放在一起,剩下的人在另一个集合$
$要求两个集合人数相等,并且同一种类的人属于同个集合$
$给出有多少种分配方式, 集合里是有顺序的,并且两个集合是不同的$
思路:
考虑一共有$f种方式将其他人和第x人同种类的人以及第y人同种类的人放在一个集合$
$我们假定 第i种类的人有c_i个, 令m = frac{n}{2}$
$那么答案就是 frac {m! cdot m! cdot f cdot 2}{c_1! cdot c_2! cdots}$
那么考虑怎么处理$f, 可以用背包,但是暴力预处理时间复杂度是O(52^{3} cdot n)$
$但是我们可以先处理好总的,注意到对于每种情况的处理只有最多两项物品的删除$
$直接删除方案数即可 这样时间复杂度就是O(52^{2} cdot n)$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define ll long long 5 #define N 100010 6 const ll MOD = (ll)1e9 + 7; 7 char s[N]; 8 int cnt[110], Hash[210]; 9 int n, q, x, y, mid; 10 ll fac[N], inv[N]; 11 ll f[110][110]; 12 ll g[N]; 13 14 ll qmod(ll base, ll n) 15 { 16 ll res = 1; 17 while (n) 18 { 19 if (n & 1) res = res * base % MOD; 20 base = base * base % MOD; 21 n >>= 1; 22 } 23 return res; 24 } 25 26 ll C(int n, int m) 27 { 28 return fac[n] * inv[m] % MOD * inv[n - m] % MOD; 29 } 30 31 int main() 32 { 33 fac[0] = 1; 34 for (int i = 1; i <= 100000; ++i) fac[i] = (fac[i - 1] * i) % MOD; 35 inv[100000] = qmod(fac[100000], MOD - 2); 36 for (int i = 100000; i >= 1; --i) inv[i - 1] = (inv[i] * i) % MOD; 37 for (int i = 1; i <= 26; ++i) Hash[‘a‘ + i - 1] = i; 38 for (int i = 27; i <= 52; ++i) Hash[‘A‘ + i - 27] = i; 39 while (scanf("%s", s + 1) != EOF) 40 { 41 n = strlen(s + 1); 42 mid = n / 2; 43 memset(cnt, 0, sizeof cnt); 44 for (int i = 1; i <= n; ++i) ++cnt[Hash[s[i]]]; 45 ll tmp = 1; 46 for (int i = 1; i <= 52; ++i) 47 if (cnt[i]) tmp = (tmp * inv[cnt[i]]) % MOD; 48 memset(f, 0, sizeof f); 49 memset(g, 0, sizeof g); 50 g[0] = 1; 51 for (int i = 1; i <= 52; ++i) if (cnt[i]) 52 { 53 for (int j = mid; j >= cnt[i]; --j) 54 g[j] += g[j - cnt[i]]; 55 } 56 for (int i = 1; i <= 52; ++i) 57 { 58 for (int j = i + 1; j <= 52; ++j) 59 { 60 if (cnt[i] == 0 || cnt[j] == 0) continue; 61 if (cnt[i] + cnt[j] > mid) continue; 62 if (cnt[i] + cnt[j] == mid) 63 { 64 f[i][j] = f[j][i] = 1; 65 continue; 66 } 67 for (int k = cnt[i]; k <= mid; ++k) 68 g[k] -= g[k - cnt[i]]; 69 for (int k = cnt[j]; k <= mid; ++k) 70 g[k] -= g[k - cnt[j]]; 71 f[i][j] = f[j][i] = g[mid - cnt[i] - cnt[j]] % MOD; 72 //printf("%d %d %lld ", i, j, f[i][j]); 73 for (int k = mid; k >= cnt[i]; --k) 74 g[k] += g[k - cnt[i]]; 75 for (int k = mid; k >= cnt[j]; --k) 76 g[k] += g[k - cnt[j]]; 77 } 78 } 79 for (int i = 1; i <= 52; ++i) if (cnt[i] && cnt[i] <= mid) 80 { 81 for (int j = cnt[i]; j <= mid; ++j) 82 g[j] -= g[j - cnt[i]]; 83 f[i][i] = g[mid - cnt[i]] % MOD; 84 //printf("%d %lld ", i, f[i][i]); 85 //printf("%d %d %lld ", i, i, f[i][i]); 86 for (int j = mid; j >= cnt[i]; --j) 87 g[j] += g[j - cnt[i]]; 88 } 89 //for (int i = 1; i <= mid; ++i) printf("%lld%c", g[i], " "[i == mid]); 90 scanf("%d", &q); 91 while (q--) 92 { 93 scanf("%d%d", &x, &y); 94 //cout << f[Hash[s[x]]][Hash[s[y]]] << endl; 95 ll res = fac[mid] * fac[mid] % MOD * 2 % MOD * tmp % MOD * f[Hash[s[x]]][Hash[s[y]]] % MOD; 96 printf("%lld ", res); 97 } 98 } 99 return 0; 100 }
以上是关于CodeCraft-19 and Codeforces Round #537 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
CodeCraft-19 and Codeforces Round #537 (Div. 2)
CodeCraft-19 and Codeforces Round #537 (Div. 2) A - Superhero Transformation
CodeCraft-19 and Codeforces Round #537 (Div. 2) - D. Destroy the Colony(动态规划+组合数学)
CodeCraft-19 and Codeforces Round #537 (Div. 2) 题解
CodeCraft-19 and Codeforces Round #537 (Div. 2) B. Average Superhero Gang Power