Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)

codeforces 868 A. Bark to Unlock(水)

题意:所有字符串都是两个小写字母组成,先给一个密码字符串,然后给N种字符串,可以选择任意种、任意数量的字符串拼成一个字符串,如果能包含密码则输出YES。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 char s[5], s1[5];
 6 int n;
 7 int main() {
 8     bool i = 0, j = 0, f = 0;
 9     scanf("%s %d", s, &n);
10     while(n--) {
11         scanf("%s", s1);
12         if(f) continue;
13         if(s[0] == s1[0] && s[1] == s1[1]) f = 1;
14         else {
15             if(s1[1] == s[0]) i = 1;
16             if(s1[0] == s[1]) j = 1;
17             f = i & j;
18         }
19     }
20     printf("%s
", f?"YES":"NO");
21     return 0;
22 }
15ms

codeforces 868 B. Race Against Time(模拟)

题意:一个钟,给出时针(1~12)、分针(0~59)、秒针(0~59)的位置,以及t1,t2(1~12,t1≠t2)所在位置,现在要从t1绕圆形钟走到t2,如果有针挡道则不能过,方向任意,问能否到达。

题解:判断三根针是否 同在 t1,t2之间的一个区间即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int main() {
 6     double h, m, s, t1, t2, f = 0;
 7     scanf("%lf%lf%lf%lf%lf", &h, &m, &s, &t1, &t2);
 8     if(t1 > t2) swap(t1, t2);
 9     t1 *= 5; t2 *= 5;
10     h += m/60.0 + s/3600.0;
11     m += s/60.0;
12     if(t1/5 <= h && h <= t2/5) {
13         if(t1 <= m && m <= t2 && t1 <= s && s <= t2)
14             f = 1;
15     }else {
16         if((m <= t1 || t2 <= m) && (s <= t1 || t2 <= s))
17             f = 1;
18     }
19     printf("%s
", f?"YES":"NO");
20     return 0;
21 }
15ms

codeforces 868 C. Qualification Rounds(模拟)

题意:n个问题,k个队伍(1 ≤ n ≤ 105, 1 ≤ k ≤ 4) ,给出每个队伍对每个问题能否解答的情况,问能否选出一些问题,使得每个队伍都 最多能解答一半的问题。

题解:只要能选出两个问题满足题意就OK。再看k这么小,可以状态压缩存一下每道题的情况,将任意两个情况相 与 ,为0则满足题意。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 bool a[16];
 6 int main() {
 7     int n, k, i, j, t, x;
 8     scanf("%d%d", &n, &k);
 9     for(i = 0; i < n; ++i) {
10         for(t = j = 0; j < k; ++j) {
11             scanf("%d", &x);
12             t = t<<1|x;
13         }
14         a[t] = 1;
15     }
16     for(i = 0; i < (1<<k); ++i)
17         for(j = i; j < (1<<k); ++j)
18             if(a[i]&&a[j]&& !(i&j)) {puts("YES");return 0;}
19     puts("NO");
20     return 0;
21 }
93ms

codeforces 868 D. Huge Strings

题意:有n个01字符串(1 ≤ n ≤ 100),每个字符串长度≤100(字符串总长≤100),标号从1~n,还有m个操作,第i个操作a,b表示把第b个字符串接在第a个字符串后面,生成一个新的字符串,标号n+i,对于每个操作产生的新字符串,求出最大正整数k,满足长为k的所有01字符串都是新字符串的子串。

//【菜的难受.jpg】看了别人代码,想了好久。。。

k最大为6。我也不知道怎么证明。。。大神说:原本给的子串最大到6(不然长度会超过100),接起来并不能增加k值。【懵】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<string>
 6 using namespace std;
 7 const int N =205;
 8 string s[N];
 9 int n, m;
10 int ans[N];
11 int fun(string x) {
12     for(int i = 6; i >= 1; --i) {
13         bool f = 1;
14         for(int j = 0; j < (1<<i); ++j) {
15             string t;
16             for(int k = 0; k < i; ++k) {
17                 if(j & (1<<k)) t += '1';
18                 else t += '0';
19             }
20             if(x.find(t) == string::npos) {f = 0; break;}
21         }
22         if(f) return i;
23     }
24     return 0;
25 }
26 int main() {
27     memset(ans, 0, sizeof(ans));
28     int i, j, a, b;
29     scanf("%d", &n);
30     for(i = 1; i <= n; ++i) cin >> s[i];
31     scanf("%d", &m);
32     for(i = n+1; i <= n+m; ++i) {
33         scanf("%d%d", &a, &b);
34         s[i] = s[a] + s[b];
35         if(s[i].length()>1000) {
36             string t = s[i].substr(0, 500) + s[i].substr(s[i].length()-500, 500);
37             s[i] = t;
38         }
39         ans[i] = max(fun(s[i]), max(ans[a], ans[b]));
40         printf("%d
" , ans[i]);
41     }
42     return 0;
43 }
15ms




原文地址:https://www.cnblogs.com/GraceSkyer/p/7630335.html