codeforces 题目 Best Binary String

目录

题目:

题目描述:

思路:

AC代码:


题目:

题目描述:

对于每个案例,给你一串可能 ' 0 ' ,' 1 ' ,' ? ' 的字符串,我称之为模板,' ? ' 表示可以替换成 ' 0 ' 或 ' 1 ' ,你的任务是,根据给出的模板,中找出其中一种字符串,它是所有根据模板设计出来的字符串中用最少 reverse 操作就能排成非递减序列的(形如00000111)

reverse 操作:指选取一个连续字串,进行逆转排序(如11010,变成01011)

思路:

首先一个问题,为了得到最终的非递减序列,什么会影响逆转操作次数?我们会发现,我们总是要把( 连续的 0 左边的 连续的 1 )挪到( 连续的 0  )右边,所以当数字越不连续的时候,需要的逆转次数就越多。此题没有要求求出最小逆转次数,所以推导到这里就够了。

所以我们的目的就变成了如何转变 ' ? ' 变成能让序列尽可能连续的情况

我们不妨对 ' ? ' 的出现位置以及旁边相邻的字符情况进行一个分析,举一些例子:

1?0?

0??1

1?1?

0?0

??1?

??0?

我们发现,为了尽可能让序列连续,我们只用让所有连续的'?'都跟距离最近的上一次出现的 ' 0 ' 或 ' 1 ' 相同就能达到最大程度的连续。如果是开头连续的 ' ? ' 我们只需要然他们与后面第一次出现的 ' 0 ' 或 ' 1 ' 相同就行(即1?0?→1100,??0?→0000)

特别的要注意,如果给你的是全 ' ? ' 的情况(如??????),我们只需要全给改成 0 或全改成 1 就行。

思路有了,具体操作请看AC代码

AC代码:

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 3e5 + 5;


int main()
{
	std::ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int t;
	cin >> t;

	while (t--)
	{
		string s;
		cin >> s;

		memset(a, 0, sizeof(a));

		//开始处理开头的连续的?
		int j = 0;

		char temp = s[0];//temp是第一个出现的 '0' 或 '1' 字符(初始值为 '?' )

		while (j < s.size() && (s[j] == temp || s[j] == '?' || temp == '?'))
		{
			if (s[j] == '1')
				temp = '1';
			else if (s[j] == '0')
				temp = '0';

			j++;
		}

		if (temp == '?')//以应对如:"??????"的情况
			temp = '1';

		for (int p = 0; p < j; p++)
			cout << temp;

		//有了第一个出现的 '0' 或 '1' 字符
		//后面只需要看上一个是什么字符就知道碰到 '?' 该输出什么字符了
		for (int i = j; i < s.size(); i++)
		{
			if (s[i] == '?')
				cout << temp;
			else
			{
				cout << s[i];
				temp = s[i];
			}
		}

		cout << '\n';

	}
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值