B - Ugu (01字符串非递减)

 

B-Ugu 

A binary string is a string consisting only of the characters 0 and 1. You are given a binary string s_1 s_2 \ldots s_ns1​s2​…sn​. It is necessary to make this string non-decreasing in the least number of operations. In other words, each character should be not less than the previous. In one operation, you can do the following:

  • Select an arbitrary index 1 \leq i \leq n1≤i≤n in the string;
  • For all j \geq ij≥i, change the value in the jj-th position to the opposite, that is, if s_j = 1sj​=1, then make s_j = 0sj​=0, and vice versa.

What is the minimum number of operations needed to make the string non-decreasing?

Input

Each test consists of multiple test cases. The first line contains an integer tt (1 \leq t \leq 10^41≤t≤104) — the number of test cases. The description of test cases follows.

The first line of each test cases a single integer nn (1 \leq n \leq 10^51≤n≤105) — the length of the string.

The second line of each test case contains a binary string ss of length nn.

It is guaranteed that the sum of nn over all test cases does not exceed 2 \cdot 10^52⋅105.

Output

For each test case, output a single integer — the minimum number of operations that are needed to make the string non-decreasing.

Sample 1

InputcopyOutputcopy
8
1
1
2
10
3
101
4
1100
5
11001
6
100010
10
0000110000
7
0101010
0
1
2
1
2
3
1
5

Note

In the first test case, the string is already non-decreasing.

In the second test case, you can select i = 1i=1 and then s = \mathtt{01}s=01.

In the third test case, you can select i = 1i=1 and get s = \mathtt{010}s=010, and then select i = 2i=2. As a result, we get s = \mathtt{001}s=001, that is, a non-decreasing string.

In the sixth test case, you can select i = 5i=5 at the first iteration and get s = \mathtt{100001}s=100001. Then choose i = 2i=2, then s = \mathtt{111110}s=111110. Then we select i = 1i=1, getting the non-decreasing string s = \mathtt{000001}s=000001.

 

题解:

        1.首先我们需要对输出的01字符进行处理,把第一个1前的0全部去除,使得相邻的0合成一个0,相邻的1合成一个1;易得处理后的字符串与原字符串所需操作次数相同

例如:

010010010

操作为:

001101101

000010010

000001101

000000010

000000001

压缩后:

101010

操作为:

010101

001010

000101

000010

000001

操作次数都是五次。

        2.这样的压缩操作最方便莫过于栈了,如果当前与栈顶元素相同,则不入栈,反之,入栈。

        3.压缩后的字符串规定以0开始,那么可能的组合有 只有 1,01,0三种,其中1只可能出现在字符串的第一位,且操作次数为0。0只可能出现在末尾。

1所需操作次数为 0

01所需操作次数为 2

0所需操作次数为1

        4.因此我们需要对1的数量计数,并保存判断最后一个值是 1 还是 0。

若末尾为1:(ct(1)-1)*2

若末尾为0:(ct(1)-1)+1

通过观察又得,所需操作次数就是第一个1(不包括第一个1)后面的字符数量!

代码如下:

#include <iostream>
#include <stack>
using namespace std;
stack<int> s;
int main()
{
	int t;
	cin >> t;
	while (t--)
	{
		int n;
		cin >> n;
		int ct =0;
		while (!s.empty())//清空栈
		{
			s.pop();
		}
		char x;
		while (n--)
		{
			cin >> x;
			if (s.empty() || s.top() != x)
			{
				s.push(x);
				if (x == '1')
					ct++;
			}
		}
		if (ct==0)//全为0时,操做次数为0
			cout << 0 << endl;
		else
		{
			if (s.top() == '1')
				cout << (ct - 1) * 2 << endl;
			else
			{
				cout << ct * 2 - 1 << endl;;
			}
		}
	}
	return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linalw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值