2022.06.16 Codeforces Round #800 (Div. 2)
A. Creep(思维题) 补
原题链接
官方标签
greedy(贪心) implementation(实现) *800
题意
组合a个0,b个1,使得到的字符串诡异程度最小(前缀01数量的绝对值之差)
思路
交替放01
补题
比赛时没看懂题意
代码
点击查看代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int t;
cin >> t;
while(t--)
{
int a, b ;
cin >> a >> b;
int n = min(a,b);
a -= n;
b -= n;
for(int i = 0;i < n;i ++)
cout << "01" ;
while(a--)
cout << "0";
while(b--)
cout << "1";
cout << endl;
}
return 0;
}
B. Paranoid String 补
原题链接
官方标签
constructive algorithms(构造算法)greedy(贪心) *1200
题意
给定一个01串,你可以进行两种操作:
1.把 01 替换成1
2.把 10 替换成0
假设字符串的长度为m,请你进行m-1次操作把一个字符串变成长度为1的串,则表示这个串符合要求。题目求的是一个长度为n的串中有多少个连续的子串可以满足要求,即[l, r]的子串符合要求的个数。
思路
通过题目中的两种操作可以知道,0可以吃掉前面的1,1可以吃掉前面的0
因此存在三种情况:
第一种情况00000001
1可以吃掉前边的任意多个0
第二种情况0000100001
先让第二个1前边的0吃掉第一个1,转化成0000000001即第一种情况
第三种情况000000011
无论怎么消除,第二个1都无法吃掉第一个1,因此会产生更多的1000001111
结论
遍历一遍字符串,如果第i-1位与第i位不相同,则ans+=i。
为什么+i?
我们从左往右扫描,表示以第i个为结尾,与前面的进行比较,如果不同的话表示不管前面取多少个都会产生 i 的贡献。
由于第一位没有前一位,则需要特判,或当ans=1时,从字符串的第二位开始遍历
补题
比赛时候没看懂题意
代码
点击查看代码
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll N = 2e5 + 10;
char s[N];
int main()
{
int t;
cin >> t;
while(t--)
{
ll n;
cin >> n >> s+1;
ll ans = 1;
for(int i = 2;i <= n;i ++)
if(s[i-1] != s[i]) ans += i;
else ans++;
cout << ans << endl;
}
return 0;
}

浙公网安备 33010602011771号