Codeforces Round #712 (Div. 2) 题解
这场前三题都是毒瘤字符串
A题 Déjà Vu
题意:
给定一个字符串,在某处插入一个字符a将其转换成非回文串。若无法转换成非回文串则输出NO,否则输出YES和转换后的字符串。
贪心题,若字符串不全为a则一定有解,只需从前往后遍历整个字符串,若对称的位置不为a就将a插入该位置即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 8 #define x first 9 #define y second 10 11 using namespace std; 12 13 typedef long long LL; 14 15 typedef long long LL; 16 typedef pair<int, int> PII; 17 18 const int N = 100010, INF = 0x3f3f3f3f; 19 20 21 int main() 22 { 23 int T; 24 cin >> T; 25 while (T -- ) 26 { 27 string s; 28 cin >> s; 29 int n = s.size(); 30 bool flag = true; 31 for (int i = 0; i < n; i ++ ) 32 if (s[i] != 'a') 33 { 34 flag = false; 35 break; 36 } 37 38 if (flag) puts("NO"); 39 else 40 { 41 puts("YES"); 42 for (int i = 0; i < n; i ++ ) 43 if (s[n - 1 - i] != 'a') 44 { 45 for (int j = 0; j < i; j ++ ) 46 cout << s[j]; 47 cout << 'a'; 48 for (int j = i; j < n; j ++ ) 49 cout << s[j]; 50 break; 51 } 52 cout << endl; 53 } 54 } 55 56 return 0; 57 }
B题 Flip the Bits
题意:
给定两个字符串a和b,对于a的前缀当其0和1数量相等时可以将其的0和1互换,要求判断能否从a字符串转换为b字符串,无解则输出NO,否则输出YES。
模拟即可,由于只需判断是否可以转换,预处理出每个前缀的0和1的数量,然后从后往前遍历,若需要改变则改变状态,无法改变状态就输出NO。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 8 #define x first 9 #define y second 10 11 using namespace std; 12 13 typedef long long LL; 14 15 typedef long long LL; 16 typedef pair<int, int> PII; 17 18 const int N = 300010, INF = 0x3f3f3f3f; 19 20 char a[N], b[N]; 21 int sum[N]; 22 23 int main() 24 { 25 int T; 26 cin >> T; 27 while (T -- ) 28 { 29 int n; 30 cin >> n >> a + 1 >> b + 1; 31 for (int i = 1; i <= n; i ++ ) 32 { 33 sum[i] = sum[i - 1]; 34 if (a[i] == '1') sum[i] ++ ; 35 } 36 37 int s = 0; 38 bool flag = true; 39 for (int i = n; i >= 1; i -- ) 40 { 41 if (sum[i] == i / 2 && i % 2 == 0) 42 { 43 if (a[i] == b[i] && s % 2 == 1) s ++ ; 44 if (a[i] != b[i] && s % 2 == 0) s ++ ; 45 } 46 else if ((a[i] == b[i] && s % 2 == 1) || (a[i] != b[i] && s % 2 == 0)) 47 { 48 flag = false; 49 puts("NO"); 50 break; 51 } 52 } 53 54 if (flag) puts("YES"); 55 } 56 57 return 0; 58 }
C题 Balance the Bits
题意:
给定一个字符串,构造两个合法的括号序列,使得其满足当s[i] == 0时两个序列相应位置的括号不相同,当s[i] == 1时两个序列相应位置括号相同。
贪心题,有点蠢。
任何平衡括号序列必须以“("开头,以")“结尾。因此,a和b必须在第一个和最后一个位置一致, 所以我们要求s1=sn=1,否则就不存在解。a和b中的开括号总数必须是n,这是偶数。s中的每个1位创建偶数个开括号,每个0位创建奇数个开括号。因此,必须有偶数个0位,否则解决方案不存在。注意,1位的数目也必须是偶数。假设这些条件成立,让我们构造一个解决方案。 假设有k个位置,其中si=1。 我们将在a和b中打开第一个k2位置 ,并在a和b中关闭最后一个k2位置。 然后,s中的0位将在哪个字符串之间交替获得开括号。
用双指针把每对1的位置都标记左右括号左边的1左括号,右边的1右括号然后从左往右遍历遇到第一个0就放左括号第二个0右括号,以此类推输出这个答案之后0位置的反过来再输出一边就行。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <map> 6 #include <queue> 7 8 #define x first 9 #define y second 10 11 using namespace std; 12 13 typedef long long LL; 14 15 typedef long long LL; 16 typedef pair<int, int> PII; 17 18 const int N = 200010, INF = 0x3f3f3f3f; 19 20 int n; 21 string s; 22 char a[N], b[N]; 23 24 int main() 25 { 26 int T; 27 cin >> T; 28 while (T -- ) 29 { 30 cin >> n >> s; 31 32 int sum = 0; 33 for (int i = 0; i < n; i ++ ) 34 if (s[i] == '0') sum ++ ; 35 36 if (sum % 2 || s[0] == '0' || s[n - 1] == '0') 37 { 38 puts("NO"); 39 continue; 40 } 41 42 int l = -1, r = n; 43 while (l < r) 44 { 45 do l ++ ; while (s[l] == '0'); 46 do r -- ; while (s[r] == '0'); 47 if (l < r) 48 { 49 a[l] = b[l] = '('; 50 a[r] = b[r] = ')'; 51 } 52 53 } 54 55 int t = 0; 56 for (int i = 0; i < n; i ++ ) 57 if (s[i] == '0') 58 { 59 if (!t) a[i] = '(', b[i] = ')'; 60 else a[i] = ')', b[i] = '('; 61 t ^= 1; 62 } 63 64 puts("YES"); 65 for (int i = 0; i < n; i ++ ) cout << a[i]; 66 cout << endl; 67 for (int i = 0; i < n; i ++ ) cout << b[i]; 68 cout << endl; 69 } 70 71 return 0; 72 }