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\n", f?"YES":"NO"); 21 return 0; 22 }
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\n", f?"YES":"NO"); 20 return 0; 21 }
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 }
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\n" , ans[i]); 41 } 42 return 0; 43 }