CF 545 Div. 2
真香 又把这事给搁下了 打了场傍晚场的CF B题才过了五百来号人 太惨了啊。 打不动 打不动
A 题目大意 :在数组中 只包含 1 2, 找出最长连续的1 1 … 2 2 … 或者 2 2 … 1 1… ,要求 1 和 2 数量相等
题解 :0(n) 扫一遍就行, 签到
Code block 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <bits/stdc++.h> using namespace std ;const int MOD = 1e9 +7 ;const int Maxn = 200005 ;int n, a[100005 ];int main () { scanf ("%d" , &n); for (int i = 0 ; i < n; i++){ scanf ("%d" , &a[i]); } int x = 1 , t = 0 ; int Max = 0 ; for (int i = 1 ; i < n; i++){ if (a[i] == a[i-1 ]) { x++; } else { t = min(t, x); Max = max(t, Max); t = x; x = 1 ; } } t = min(t, x); Max = max(t, Max); printf ("%d\n" , Max * 2 ); return 0 ; }
B 题目大意 :有 n 个人, 每个人会表演小丑和杂技, 或者什么都不会, 或只会其一。 需要分成两组,每组 n / 2 个人,要求第一组中会小丑的人和第二组会杂技的人一样多!
题解 :解方程, 暴力枚举 疯狂判断
Code block 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std ;const int N = 10005 ; int n;char c[N], a[N];vector <int > V[6 ]; int main () { scanf ("%d" , &n); scanf ("%s" , c + 1 ); scanf ("%s" , a + 1 ); for (int i = 1 ; i <= n; i++){ if (c[i] == '0' ){ if (a[i] == '0' ) V[0 ].push_back(i); else V[1 ].push_back(i); } else { if (a[i] == '0' ) V[2 ].push_back(i); else V[3 ].push_back(i); } } int A = V[0 ].size(), B = V[1 ].size(), C = V[2 ].size(), D = V[3 ].size(); for (int i = 0 ; i <= C; i++){ for (int j = 0 ; j <= B; j++){ if ((j + D - i) % 2 == 0 && (j + D - i) / 2 >= 0 && n / 2 - (B - j) - i - (j + D -i) / 2 >= 0 && n / 2 - j - (C - i)- (D- (j + D -i) / 2 ) >= 0 && (j + D - i) / 2 <= D ){ for (int k = 0 ; k < n / 2 - (B - j) - i - (j + D -i) / 2 ; k++) printf ("%d " , V[0 ][k]); for (int k = 0 ; k < B - j; k++) printf ("%d " , V[1 ][k]); for (int k = 0 ; k < i; k++) printf ("%d " , V[2 ][k]); for (int k = 0 ; k < (j + D - i) / 2 ; k++) printf ("%d " , V[3 ][k]); return 0 ; } } } printf ("-1\n" ); return 0 ; }
C 题目大意 :有 n * m 的一个矩阵,对于每一个点,需要对其一整行加上一整列近行从小到大编号 要求最大编号尽量小,可以出现1 1 2 2 2 3 这种编号方法,题目中有说明只要表明两两之间的相对关系大小即可。
题解 :对每一列每一行分别排序,然后对于其中的每一个点,只要二分查找齐对应的位置,注意行列影响。
Code block 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 #include <iostream> #include <cstring> #include <vector> #include <algorithm> #include <string> using namespace std ;const int N = 1005 ;int n, m;int h[N][N];vector <int > c[N], r[N];int main () { scanf ("%d%d" , &n, &m); for (int i = 1 ; i <= n; i++){ for (int j = 1 ; j <= m; j++){ scanf ("%d" , &h[i][j]); } } for (int i = 1 ; i <= n; i++){ for (int j = 1 ; j <= m; j++){ r[i].push_back(h[i][j]); } sort(r[i].begin(),r[i].end()); r[i].erase(unique(r[i].begin(), r[i].end()), r[i].end()); } for (int i = 1 ; i <= m; i++){ for (int j = 1 ; j <= n; j++){ c[i].push_back(h[j][i]); } sort(c[i].begin(), c[i].end()); c[i].erase(unique(c[i].begin(), c[i].end()), c[i].end()); } for (int i = 1 ; i <= n; i++){ for (int j = 1 ; j <= m; j++){ int x = lower_bound(r[i].begin(), r[i].end(), h[i][j]) - r[i].begin(); int y = lower_bound(c[j].begin(), c[j].end(), h[i][j]) - c[j].begin(); int a = r[i].end() - lower_bound(r[i].begin(), r[i].end(), h[i][j]); int b = c[j].end() - lower_bound(c[j].begin(), c[j].end(), h[i][j]); printf ("%d " , max(x, y) + max(a, b)); } printf ("\n" ); } return 0 ; }
D 题目大意 :有两个字符串 S,T,只包含 0 1 。现在需要把字符串 S 重新排序,使 S 中包含最多的 T,根据题目是可重复子串。
题解 :KMP 计算 next数组。 每当 T 构造完后,直接从它的相同前缀后一个开始构造。直到 0 1 有一个先用完。
Code block 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream> #include <cstring> #include <algorithm> #include <cmath> using namespace std ;const int N = 500005 ;char s[N], t[N], ans[N];int nxt[N], cnt[N];int main () { scanf ("%s%s" , s + 1 , t + 1 ); int m = strlen (t + 1 ); int len = strlen (s + 1 ); for (int i = 1 ; i <= len; i++){ cnt[s[i] - '0' ]++; } int p = 0 ; for (int i = 2 ; i <= m; i++){ while (p && t[p+1 ] != t[i]) p = nxt[p]; if (t[p+1 ] == t[i]) p++; nxt[i] = p; } p = 1 ; for (int i = 1 ; i <= len; i++){ if (cnt[t[p] - '0' ] == 0 ){ for (int j = i; j <= len; j++){ ans[j] = ((t[p] - '0' ) ^ 1 ) + '0' ; } break ; } cnt[t[p] - '0' ]--; ans[i] = t[p]; p++; if (p > m) p = nxt[m] + 1 ; } for (int i = 1 ; i <= len; i++){ printf ("%c" , ans[i]); } return 0 ; }