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;
}
posted @ 2022-06-17 17:35  HeyStar  阅读(57)  评论(0)    收藏  举报