题解——P14258 好感(favor)
bianry_carrots · · 题解
题目传送门
题目大意
给你一个
思路
本题考察贪心。
先只考虑全部翻成反面朝上的情况。
因为每次操作都会且仅会使一个浮板翻面,所以把原来就是反面的浮板翻掉肯定不是最优的。同时,如果对第
从后往前贪心,若第
举个栗子,样例里的 1011100 会经历如下过程
1011100->0011100->0110000->1000000->0000000
全部翻成正面朝上的情况同理,然后把算出来的两个答案取
Code
如果暴力模拟这个过程,那么 T 飞了,时间复杂度是
但是我们可以使用嘿科技 deque 来模拟,这样把时间复杂度降到了
最后,十年 OI 一场空,不开 见祖宗!
#include <bits/stdc++.h>
using namespace std;
const int N = 1145140;
#define endl '\n'
#define int long long //防止溢出
deque <char> q; //STL niubi!!!
string s;
int n;
void solve() {
cin >> n;
cin >> s;
for (int i = 0; i < n; i++) q.push_back(s[i]);
int ans1 = 0, ans2 = 0;
while (!q.empty()) {
if (q.back() == '1') {
if (q.size() == 1) {
ans1++;
q.pop_back();
break;
} //特判一下,防止RE
ans1 += q.size();
if (q.front() == '1') ans1++;//确保第一个浮板是反面
q.pop_front();
q.pop_back();
} else q.pop_back();
} //全部翻成反面朝上
for (int i = 0; i < n; i++) q.push_back(s[i]);
while (!q.empty()) {
if (q.back() == '0') {
if (q.size() == 1) {
ans2++;
q.pop_back();
break;
} //特判一下,防止RE
ans2 += q.size();
if (q.front() == '0') ans2++;//确保第一个浮板是正面
q.pop_front();
q.pop_back();
} else q.pop_back();
}//全部翻成正面朝上
cout << min(ans1, ans2);
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
solve();
cout << endl;
}//多测
return 0;
}