[cf] Codeforces Round #789 (Div. 2)

8 篇文章 0 订阅
7 篇文章 0 订阅

前言

传送门:

B2.

t a g : tag : tag:贪心 分治 字符串
给你一串 01 01 01 字符串,询问将其变为 g o o d good good的最小操作次数和最终状态的最小段数

操作 :
1 1 1变为 0 0 0,将 0 0 0变为 1 1 1

g o o d : good : good:
当且仅当连续的 11... 11... 11..., 00.. 00.. 00..个数都为偶数的时候

思路 :
因为最终状态是 偶数

所以必然存在 s [ i ] = s [ i + 1 ] s[i]=s[i+1] s[i]=s[i+1],因此对于 s [ i ] ≠ s [ i + 1 ] s[i]\neq s[i+1] s[i]=s[i+1]的位置,我们必然需要掏出一个操作

那么怎么考虑最小段数呢 ?

显然对于原有的 00 , 11 00,11 00,11这种组合我们是不需要进行拆分的

因此我们只需要考虑 01 , 10 01,10 01,10,那么我们遇到 01 , 10 01,10 01,10这种组合的时候是把它变为 00 00 00还是 11 11 11

我们贪心的考虑将其放入最近的分组里面

最后判断答案,发现正确

code :

void solve(){
	int n;cin>>n;
	string s;cin>>s;
	
	int ans = 0 ;
	int cnt = 0 ;
	int pre = -1;
	
	for(int i=0;i<n;i+=2){
		if(s[i] == s[i+1]){
			if(pre ==-1){
				pre = s[i] -'0';
				cnt ++;
			}else if(pre != (s[i]- '0')){
				pre = s[i] -'0';
				cnt++;
			}
		}else ans++;
	}
	
	if(pre ==-1) cnt = 1;
	cout<<ans<<" "<<cnt<<endl;
	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值