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 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值