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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

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 }
View Code

 

以上是关于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

CodeCraft-19 and Codeforces Round #537 Div. 2