题目描述:
给你一段01串,请你将所有0放在1前面,但只能是一块一块的移动,请你求出分块的最小数目
如
1010101
⇒
1
∣
01
∣
0
∣
1
∣
0
∣
1
0
∣
0
∣
01
∣
1
∣
1
∣
1
1010101 \Rightarrow 1 |01|0|1|0|1 \\ 0|0|01|1|1|1
1010101⇒1∣01∣0∣1∣0∣10∣0∣01∣1∣1∣1
思路:
此题思路就是除了第一个 01 串算 1 次 , 其余全部算 2 次 1010101 ⇒ 1 ∣ 01 ∣ 0 ∣ 1 ∣ 0 ∣ 1 假设不这么分就会出现 2 个类似 0...1 的串这样的串无论如何都不能拼成所有 0 在 1 前面的串 即分成 1 ∣ 01 ∣ 01 ∣ 0 ∣ 1 , 不管怎么样都无法拼成题意 但这样代码不太好写 , 我们反过来想 , 先都切割 , 如果存在 01 串就将切割数减一 此题思路就是除了第一个01串算1次,其余全部算2次\\ 1010101 \Rightarrow 1 |01|0|1|0|1\\ 假设不这么分就会出现2个类似0...1的串这样的串无论如何都不能拼成所有0在1前面的串\\ 即分成1|01|01|0|1,不管怎么样都无法拼成题意\\ 但这样代码不太好写,我们反过来想,先都切割,如果存在01串就将切割数减一 此题思路就是除了第一个01串算1次,其余全部算2次1010101⇒1∣01∣0∣1∣0∣1假设不这么分就会出现2个类似0...1的串这样的串无论如何都不能拼成所有0在1前面的串即分成1∣01∣01∣0∣1,不管怎么样都无法拼成题意但这样代码不太好写,我们反过来想,先都切割,如果存在01串就将切割数减一
代码:
#include <bits/stdc++.h>
using namespace std;
int t;
string s;
int main(){
cin >> t;
while(t--){
cin >> s;
int n=s.size(),res=1;
bool flag=0;
for(int i=0;i<n-1;i++){
res+=(s[i]!=s[i+1]);//如果是分界线,切割数加一
flag|=(s[i]=='0' && s[i+1]=='1');//如果存在一个01串,就在结果的时候减一
}
cout << res-flag << endl;
}
return 0;
}