#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章