2021gdut月赛 H捣蛋鬼

ddg是非常有意思的一道贪心题,月赛的时候确实把我橄榄了,因为总是想起肥猪的钢琴床,所以全程我都在想dp方程,但是水平拉胯的我确实想不出,看了题解才明白这道题的精髓所在

 下面是ac代码,结合代码的注释和题解理解这道题应该不会很难

捣蛋鬼就用拼音首字母ddg指代了

没学过c++看起来应该也不会有压力,输入输出的差异并不是重点,主要是for循环语句

#include <bits/stdc++.h>
using namespace std; 
int main()
{
	int n;
	cin >> n;
	string s;
	cin >> s;//输入01串 
	int cnt1 = 0;//cnt1会告诉我们有几个ddg 
	for(int i = 0;i < n;++i)
	{
		if(s[i] == '1') cnt1++;
	}
	if(cnt1 & 1) {
	    cnt1 = cnt1/2+1;
    }//找到ddg为奇数情况下中间的ddg 
	else {
	    cnt1 /= 2;
	}//找到偶数情况中间的ddg 
	int cnt2 = 0; //cnt2用来标记0的个数,事实上很容易明白他就表示当遇到1时,1要到正确位的交换次数 
	int flag = 0;//最中间的ddg的坐标(这里的中间是指ddg的最中间,不是包括了好孩子) 
	for(int i = 0;i < n;++i)
	{
		if(s[i] == '1') cnt2++; 
		if(cnt2 == cnt1) {flag = i; break;}//找到c位出道的ddg 
	}
	int cnt0 = 0;
	long long ans = 0;//特别注意开long long 
	for(int i = flag-1;i >= 0;--i)
	{
		if(s[i] == '0') cnt0++;//加上左边的ddg换位次数 
		else if(s[i] == '1') ans += cnt0;
	}
	cnt0 = 0;
	for(int i = flag+1;i < n;++i)
	{
		if(s[i] == '0') {
		    cnt0++;
		}else if(s[i] == '1') {
		    ans += cnt0;//加上右边的ddg换位次数 
	    }
	}
	cout << ans << endl;//输出答案,ac 
	return 0;
}

(一个long long不知道让多少人深夜流泪,所以说ddg真的讨厌)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值