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真的讨厌)