这场前三题都是毒瘤字符串
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 }