ZZULIOJ 2626 小H玩游戏

题目链接

博主太懒,不想写题目描述了

思路:

首先可以发现最终的结果和操作顺序无关,因此可以从头开始操作,遇到1就操作一次,更新后面的值,但是如果每次更新后面的字符串时间消耗太大,因此可以用一个数组记录每个位置的数字被操作的次数,操作了偶数次相当于没有操作,根据操作次数和原本的数字可以判断当前的数字

于是~问题转换成了怎么记录操作次数

可以用差分区间的方法,对于每一个位置,如果是1,后面的数字都要反转,也就是后面的数字的操作次数加1,对应cnt[ i ]++,每次循环到一个新的位置时线计算前缀和(即当前位置的值),因为每次操作第一个可以保证第一个前面没有1,所以可以一边循环一边求差分数组的前缀和,时间复杂度线性

#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
const int N = 100010;
char s[N];
int cnt[N], sum[N];
int main()
{
	ios::sync_with_stdio(0);
	int n;
	cin >> n;
	while (n--){
		memset(cnt, 0, sizeof cnt);
		memset(sum, 0, sizeof sum);
		cin >> s;
		int len = strlen(s);
		int res = 0;
		if(s[0] == '1'){
			res++;
			cnt[1]++;
			cnt[len]--;
		}
		for (int i = 1; i < len; i++){
			sum[i] = sum[i - 1] + cnt[i];
			if(s[i] == '1' && sum[i] % 2 == 0){
				res++;
				cnt[i + 1]++;
				cnt[len]--;
			}
			else if(s[i] == '0' && sum[i] % 2 == 1){
				res++;
				cnt[i + 1]++;
				cnt[len]--;
			}
		}
		if(res & 1)cout << "Yes\n";
		else cout << "No\n";
	}
	return 0;
}
发布了143 篇原创文章 · 获赞 11 · 访问量 8198

猜你喜欢

转载自blog.csdn.net/weixin_43701790/article/details/103674291