codeforces 题目 Flip the Bits

目录

题目:

题目描述:

思路:

AC代码:


题目:

题目描述:

给你两串长度为 n 的 01字符串 a 和 b ,

操作要求:若从开头到当前位置区间内 0 的总数和 1 的总数相同,则可以进行逆转操作( 区间内的 0 变 1 , 区间内的1 变 0 )

问能不能经过有限次操作,将 a 串转化为 b 串。

思路:

若需要逆转的连续区间  恰好 处于 前缀区间01个数相同 的两个位置之间(不用相邻),则可以通过两次操作将此段区间逆转后不影响区间外的数。(情况如下图)

绿色的线代表的是前面 1 和 0 个数相同的位置(可以进行翻转的位置),经过黄色和粉色两次操作,我们就可以将红色区间进行翻转且不影响外部。

若需要逆转的连续区间  并非恰好 处于 前缀区间01个数相同 的两个位置之间,则要么不能将区间转化完全,要么在转化的过程中会影响外部不用转化的区间,从而导致,a串必定不能转化成b串。(如下图:)

所以,我们的目标就变成了,记录前缀区间 01个数相同的位置,找 a 串需要逆转的几个连续区间是否完全对应上面记录的位置即可。

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

AC代码:

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

const int N = 3e5 + 5;

char a[N];
char b[N];

void solve()
{
	bitset<N>vis;//记录前缀区间01个数相同的右端点位置
	vis[0] = 1;

	int n;
	cin >> n;

	cin >> a + 1 >> b + 1;

	int sum = 0;
	int flag = 1;//标志着是否能操作成功,初始默认成功

	for (int i = 1; i <= n; i++)
	{
		if (a[i] == '0')
			sum++;
		else
			sum--;

		if (sum == 0)    //当sum为0的时候说明前面0和1的个数相同
			vis[i] = 1;
	}

	for (int i = 1; i <= n;)
	{
		if (a[i] == b[i])
		{
			i++;
			continue;
		}

		int j = i + 1;
		while (j <= n && a[j] != b[j])
			j++;

		if (vis[i - 1] && vis[j - 1])
			i = j;
		else
		{
			flag = 0;
			break;
		}
	}
	cout << (flag ? "YES" : "NO") << '\n';
}

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

	int t; cin >> t;
	while (t--)
		solve();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值