1. 程式人生 > >CodeCraft-19 and Codeforces Round #537 (Div. 2)

CodeCraft-19 and Codeforces Round #537 (Div. 2)

時間復雜度 sizeof ont %d hack and close splay eat

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\n", 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\n", 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\n", 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\n", i, f[i][i]);
 85             //printf("%d %d %lld\n", 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], " \n"[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\n", res);
 97         }
 98     }
 99     return 0;
100 }
View Code

CodeCraft-19 and Codeforces Round #537 (Div. 2)