#646 (Div. 2)B. Subsequence Hate

題目描述

Shubham has a binary string s. A binary string is a string containing only characters “0” and “1”.
He can perform the following operation on the string any amount of times:
Select an index of the string, and flip the character at that index. This means, if the character was “0”, it becomes “1”, and vice versa.
A string is called good if it does not contain “010” or “101” as a subsequence — for instance, “1001” contains “101” as a subsequence, hence it is not a good string, while “1000” doesn’t contain neither “010” nor “101” as subsequences, so it is a good string.
What is the minimum number of operations he will have to perform, so that the string becomes good? It can be shown that with these operations we can make any string good.
A string a is a subsequence of a string b if a can be obtained from b by deletion of several (possibly, zero or all) characters.

Input

The first line of the input contains a single integer t (1≤t≤100) — the number of test cases.
Each of the next t lines contains a binary string s (1≤|s|≤1000).

Output

For every string, output the minimum number of operations required to make it good.

Example

input
7
001
100
101
010
0
1
001100
output
0
0
1
1
0
0
2

Note

In test cases 1, 2, 5, 6 no operations are required since they are already good strings.
For the 3rd test case: “001” can be achieved by flipping the first character — and is one of the possible ways to get a good string.
For the 4th test case: “000” can be achieved by flipping the second character — and is one of the possible ways to get a good string.
For the 7th test case: “000000” can be achieved by flipping the third and fourth characters — and is one of the possible ways to get a good string.

題目大意

給你一個只有0和1組成的字符串,你每次操作可以將某一位上的0翻轉成1,1翻轉成0。求至少反轉多少次才能使得字符串中沒有“101”或者“010”。

題目分析

爲了讓字符串中沒有“010”或“101”,那麼我們修改後的字符串只有:全是0,全是1,一邊是0一邊是1(如0001111)這三種結構。

對於一邊是0一邊是1這種結構,會有一個分割線,分割線的左邊都修改爲了一種數,而右邊都修改成了另一種數。如000|1111,分割線左邊全修改成了0,右邊全修改成了1。
而對於全修改成0/1的情況,也可以看成是分割線在最左邊或最右邊的情況(如:|000000,|1111111)。

因此,我們可以枚舉這個分割線的所有位置,並計算出分割線在該位置時需要的最小修改次數,最後找出最小的修改次數即可。

代碼如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <map>
#include <unordered_map>
#include <queue>
#include <vector>
#include <set> 
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=1005;
int main()
{
    int t;
	cin>>t;
	while(t--)
	{
		string s;
		cin>>s;
		int cnt0=0,cnt1=0;        //表示分割線的右邊的0/1數量
		//因爲一開始分割線位於字符串的最左邊(|00010010)
		for(int i=0;i<s.size();i++)   //所以一開始cnt存的是整個字符串中0/1的數量
		if(s[i]=='0') cnt0++;
		else cnt1++;
		
		int k0=0,k1=0;           //表示分割線左邊0/1的數量(一開始都是0)
		int ans=min(cnt0,cnt1);  //記錄答案(全局最小修改次數)
		for(int i=0;i<s.size();i++)  //枚舉分割線的位置
		{
			if(s[i]=='0') k0++,cnt0--;   //分割線右移,cnt和k相應的增減
			else k1++,cnt1--;
			
			ans=min(ans,min(k0,k1)+min(cnt0,cnt1));  //跟新最小值
		}
		cout<<ans<<endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章