Codeforces Round #561 (div. 2)

时间太晚就没有打,随便看了一下题,当了嘴巴选手。结果发现题目简单到超出想象。

题目链接:https://codeforces.com/contest/1166


A:

上来就卡题意,其实用map维护一下直接秒杀。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define pb push_back
 4 #define mp make_pair
 5 #define sot(a,b) sort(a+1,a+1+b)
 6 #define rep(i,a,b) for (int i=a;i<=b;i++)
 7 #define eps 1e-8
 8 #define int_inf (1<<30)-1
 9 #define ll_inf (1LL<<62)-1
10 #define lson curPos<<1
11 #define rson curPos<<1|1
12 
13 using namespace std;
14 
15 map<char, int>m;
16 int n;
17 string s;
18 
19 int main()
20 {
21     m.clear();
22     cin >> n;
23     while (n--)
24     {
25         cin >> s;
26         m[s[0]]++;
27     }
28     int ans = 0;
29     for (auto i : m)
30     {
31         if (i.second <= 2) continue;
32         int tmp = i.second / 2;
33         ans += (tmp - 1) * tmp / 2;
34         if (i.second & 1) tmp++;
35         ans += (tmp - 1) * tmp / 2;
36     }
37     cout << ans << endl;
38     return 0;
39 }
View Code

B:

只要能把k分解为两个大于等于5的数相乘,暴力填上aeiou就完事了。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curPos<<1
15 #define rson curPos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 int k, n, m, flag = 0;
21 string s = "aeiou";
22 
23 int main()
24 {
25     scanf("%d", &k);
26     rep1(i, 1, k)
27     if (k % i == 0 && i >= 5 && k / i >= 5)
28     {
29         n = i, m = k / i, flag = 1; break;
30     }
31     if (!flag) return puts("-1"), 0;
32     rep0(i, 0, n) rep0(j, 0, m) printf("%c", s[(i + j) % 5]);
33     puts("");
34     return 0;
35 }
View Code

C:

给定一维坐标系上的n个数(点),问有多少对数x,y满足线段 [abs(x-y),abs(x+y)]能覆盖线段[abs(x),abs(y)]。

看似麻烦。但是留意到被覆盖的线段是[abs(x),abs(y)]而不是[x,y],所以这道题跟正负没有任何关系,直接取绝对值即可。判断大的线段能不能覆盖小的线段,就要看max(x,y)/min(x,y)是否大于2,如果大于2则不能覆盖。显然二分查找。

于是时间复杂度O(nlogn),是这段时间cf contest出过最傻逼的C题了。(赛后看了一眼队友代码,怎么你们还分类大讨论啊???)

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curPos<<1
15 #define rson curPos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 2e5 + 10;
21 int a[maxn], n;
22 ll ans = 0;
23 
24 int main()
25 {
26     scanf("%d", &n);
27     rep1(i, 1, n) scanf("%d", &a[i]), a[i] = abs(a[i]);
28     sot(a, n);
29     rep0(i, 1, n) ans += upper_bound(a + i, a + 1 + n, 2 * a[i]) - a - i - 1;
30     printf("%lld\n", ans);
31     return 0;
32 }
View Code

D:

直接枚举序列长度+二分。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8 #define sot(a,b) sort(a+1,a+1+b)
 9 #define rep1(i,a,b) for(int i=a;i<=b;++i)
10 #define rep0(i,a,b) for(int i=a;i<b;++i)
11 #define eps 1e-8
12 #define int_inf 0x3f3f3f3f
13 #define ll_inf 0x7f7f7f7f7f7f7f7f
14 #define lson curPos<<1
15 #define rson curPos<<1|1
16 /* namespace */
17 using namespace std;
18 /* header end */
19 
20 const int maxn = 1e2 + 10;
21 ll n, m, q, a, b, tot = 1, pre[maxn], used[maxn];
22 
23 int main()
24 {
25     scanf("%d", &q);
26     pre[1] = 1;
27     rep1(i, 2, 50) //弄个前缀和
28     {
29         pre[i] = tot;
30         tot += pre[i];
31     }
32     while (q--)
33     {
34         scanf("%lld%lld%lld", &a, &b, &m);
35         bool flag = false;
36         rep1(k, 1, 50) //枚举序列长度
37         {
38             for (int j = k - 1; j > 0; j--) used[j] = 1; //init
39             ll curr = pre[k] * a;
40             rep0(j, 1, k) curr += pre[j];
41             if (curr > b) break; //直接计算最后一项,若不符合,之后都无解
42             for (int j = k - 1; j > 0; j--)
43             {
44                 ll l = 0, r = m - 1; //binary search
45                 while (l <= r)
46                 {
47                     ll mid = l + r >> 1;
48                     if (curr + mid * pre[j] > b) r = mid - 1;
49                     else l = mid + 1;
50                 }
51                 used[j] = --l + 1;
52                 curr += pre[j] * l;
53             }
54             if (curr == b) //有解
55             {
56                 flag = true;
57                 ll curr = a, currsum = 0;
58                 printf("%d", k);
59                 rep1(j, 1, k)
60                 {
61                     printf(" %lld", curr);
62                     currsum += curr;
63                     curr = currsum + used[k - j];
64                 }
65                 puts("");
66                 break;
67             }
68         }
69         if (!flag) puts("-1");
70     }
71     return 0;
72 }
View Code

E:

数论题,完全莫得想法,据说是个结论题(反正数论全靠队友2333)。贴队友代码(via. rsqppp)好了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 int f[60][15000];
 7 int main()
 8 {
 9     int m,n;
10     scanf("%d%d",&m,&n);
11     for(int i = 1;i <= m;i++){
12         int num;
13         scanf("%d",&num);
14         for(int j = 1;j <= num;j++){
15             int x;
16             scanf("%d",&x);
17             f[i][x] = 1;
18         }
19     }
20     for(int i = 1;i <= m;i++){
21         for(int j = 1;j <= m;j++){
22             int flag = 0;
23             for(int k = 1;k <= n;k++){
24                 if(f[i][k] && f[j][k]){
25                     flag = 1;
26                     break;
27                 }
28             }
29             if(flag == 0){
30                 printf("impossible\n");
31                 return 0;
32             }
33         }
34     }
35     printf("possible\n");
36     return 0;
37 }
View Code

 F:

其实不是很想做,不过看到是数据结构题,还是要主动背起这口锅……就是个并查集维护动态图的题。

 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define sot(a,b) sort(a+1,a+1+b)
 8 #define rep1(i,a,b) for(int i=a;i<=b;++i)
 9 #define rep0(i,a,b) for(int i=a;i<b;++i)
10 #define eps 1e-8
11 #define int_inf 0x3f3f3f3f
12 #define ll_inf 0x7f7f7f7f7f7f7f7f
13 #define lson curPos<<1
14 #define rson curPos<<1|1
15 /* namespace */
16 using namespace std;
17 /* header end */
18 
19 const int maxn = 1e5 + 10;
20 int n, m, c, q, fa[maxn];
21 map<int, int>mp[maxn];
22 set<int>own[maxn];
23 
24 int findFa(int v)
25 {
26     return fa[v] < 0 ? v : fa[v] = findFa(fa[v]);
27 }
28 
29 void merge(int u, int v)
30 {
31     if ((u = findFa(u)) == (v = findFa(v))) return;
32     if ((int)own[u].size() > (int)own[v].size()) swap(u, v);
33     fa[u] = v;
34     for (auto i : own[u]) own[v].insert(i);
35     own[u].clear();
36 }
37 
38 void addedge(int u, int v, int c)
39 {
40     if (mp[u].count(c)) merge(v, mp[u][c]);
41     if (mp[v].count(c)) merge(u, mp[v][c]);
42     mp[u][c] = v; mp[v][c] = u;
43     own[findFa(v)].insert(u);
44     own[findFa(u)].insert(v);
45 }
46 
47 int main()
48 {
49     memset(fa, -1, sizeof(fa));
50     scanf("%d %d %d %d ", &n, &m, &c, &q);
51     rep1(i, 1, m)
52     {
53         int u, v, c; scanf("%d %d %d ", &u, &v, &c);
54         u--, v--;
55         addedge(u, v, c);
56     }
57     while (q--)
58     {
59         char op; int x, y, z;
60         op = getchar();
61         scanf("%d %d ", &x, &y); x--, y--;
62         if (op == '+')
63         {
64             scanf("%d ", &z);
65             addedge(x, y, z);
66         }
67         else
68         {
69             int rx = findFa(x);
70             if (rx == findFa(y) || own[rx].find(y) != own[rx].end())
71                 puts("Yes");
72             else puts("No");
73         }
74     }
75     return 0;
76 }
View Code

 

posted @ 2019-05-18 11:04  JHSeng  阅读(343)  评论(0编辑  收藏  举报