整理的算法模板合集: ACM模板
实际上是一个全新的精炼模板整合计划
Codeforces Round #712 Div.2(A ~ F) 题解
比赛链接:https://codeforces.com/contest/1504
- A. 回文串
- B. 思维
- C. 构造题,括号序列匹配
- D. 交互题,黑白染色
- E. 最短路,贪心
- F. 贪心
目录
A. Déjà Vu
Problem
给你一个字符串。问能否在该字符串里插入一个字母 a
,使得它不是回文字符串。
Solution
显然不想让他变成回文字符串,那就破坏它成为回文字符串的条件,我们只能插入字符 a
,所以我们直接算一下该字符串前缀、后缀里各有有几个 a
,把我们能插入的 a
放到 a
多的地方即可。
Code
// Problem: A. Déjà Vu
// Contest: Codeforces - Codeforces Round #712 (Div. 2)
// URL: https://codeforces.com/contest/1504/problem/A
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
const int N = 5007;
int t;
string s;
void solve()
{
cin >> s;
int len = s.length();
int cnt1 = 0, cnt2 = 0;
for(int i = 0; i < len; ++ i) {
if(s[i] == 'a') {
cnt1 ++ ;
}
else break;
}
for(int i = len - 1; i >= 0; -- i) {
if(s[i] == 'a') {
cnt2 ++ ;
}
else break;
}
if(cnt1 == len) puts("NO");
else if(cnt1 > cnt2) {
puts("YES");
string ans = "a";
ans += s;
cout << ans << endl;
}
else {
puts("YES");
string ans = "";
ans += s;
ans += "a";
cout << ans << endl;
}
}
int main()
{
scanf("%d", &t);
while(t -- ) {
solve();
}
return 0;
}
B. Flip the Bits
Problem
给你两个01字符串 a , b a,b a,b,你有一种可以使用无限次的操作:对于字符串 a a a ,你可以选择 a a a 的一个前缀子串(从0开始往后,选择一个连续的子串),若该子串的01数量相同,则你可以把该子串的01翻转,即:将0变成1,1变成0,问能否通过该操作使得 a , b a,b a,b 字符串相等。
Solution
我们拥有无限次的操作次数,所以如果抛去01数量相等这个交换条件,从后往前只要不一样就疯狂交换,是一定可以让两个字符串相等的。
现在多了一个必须01相等才能交换的条件,显然01交换以后01的数量是不变的,所以我们可以判断一下哪些是必须交换的,然后看他能不能交换即可。
如何判断是否必须交换,因为整体前缀交换就意味着相邻的两个字符的相对关系是一直保持不变的,原来是相同,前缀交换以后还是相同的,所以显然判断条件就是对于第 i i i 个字符,若 a [ i ] a[i] a[i] 、 a [ i + 1 ] a[i + 1] a[i+1] 的关系(相同还是不同),与 b [ i ] b[i] b[i] 、 b [ i + 1 ] b[i + 1] b[i+1] 的关系是相反的,那么从 i i i 开始的前缀就必须交换一次,我们判断一下这里的前缀01数量是否相同即可。
最后特判一下最后一个字符是否合法即可。
Code
// Problem: B. Flip the Bits
// Contest: Codeforces - Codeforces Round #712 (Div. 2)
// URL: https://codeforces.com/contest/1504/problem/B
// Memory Limit: 256 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
const int N = 50007;
int n, m, t;
string a, b;
bool work()
{
int cnt = 0;
for(int i = 0; i < n; ++ i) {
if(a[i] == '1') cnt ++ ;
else cnt -- ;
if(i == n - 1) {
if(a[i] == b[i] || cnt == 0) return true;
else return false;
}
if(((a[i] == a[i + 1]) != (b[i] == b[i + 1])) && cnt != 0)
return false;
}
return true;
}
void solve()
{
scanf("%d", &n);
cin >> a >> b;
if(work()) {
puts("YES");
}
else puts("NO");
}
int main()
{
scanf("%d", &t);
while(t -- ) {
solve();
}
return 0;
}
C. Balance the Bits
Problem
给你一个01字符串 s s s,要求构造出两个合法的长度为 n n n 的括号序列 a , b a,b a,b。
满足:
若: s i = 1 s_i=1 si=1,则 a i = b i a_i=b_i ai=bi
若: s i = 0 s_i=0 si=0,则 a i ≠ b i a_i≠b_i ai