CF1861C Queries for the Array

CF1861C Queries for the Array

不太一样的写法,感觉比较容易理解一点。码量也比较短。

首先我们要发现:一个序列如果目前是升序的,那么它不管删多少个数(中间不再加数),最终还是升序的;如果目前不是升序,那么不管加多少个数,最终也不是升序。

这启发我们用两个数组 upidowni 记录当前长度为 i 的序列是升序还是不是升序。如果存在一个时刻序列长度为 i,并且 upidowni 都是 1,也就是既是升序也不是升序,那么就不合法。(情况1)

不合法的情况还有一种,就是当序列长度小于等于 1 时,操作序列说此时不是升序,那么根据题意,也是不合法的。(情况2)

updown 的转移非常简单,如果长度 now1,并且 upnow=1,那么 upnow1=upnow,同时把 upnow=downnow=0,表示未知;如果长度 now1,那么只需要转移 downnow+1=downnow

所以这题我们只需要发现上面的性质就好写了,虽然比别人多个数组来做有点蠢。

AC code:

#include <bits/stdc++.h>
typedef long long ll;
int read() {
	int x = 0, f = 1;
	char c = getchar();
	while(!isdigit(c)) {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(isdigit(c)) {
		x = (x << 3) + (x << 1) + (c - '0');
		c = getchar();
	}
	return x * f;
}
int t;
char a[200010];
int up[200010], down[200010];
void Solve() {
	t = read();
	while(t--) {
		std::cin >> a + 1;
		int n = strlen(a + 1), now = 0;
		bool flg = 0;
		memset(up, 0, sizeof(up));
		memset(down, 0, sizeof(down)); //这样初始化没有 tle 有点神奇。
		for(int i = 1; i <= n; i++) {
			if(a[i] == '+' || a[i] == '-') {
				if(a[i] == '+') {
					down[now + 1] = down[now];
					now++;
				}
				else {
					down[now] = 0;
					if(up[now]) up[now - 1] = up[now]; //注意判断,因为这个调了好久qwq
					up[now] = 0;
					now--;
				}
			}
			else {
				if(now <= 1 && a[i] == '0') flg = 1; //情况2
				if(a[i] == '1') up[now] = 1;
				else down[now] = 1; //根据操作序列更新数组
				if(up[now] && down[now]) flg = 1; //情况1
			}
		}
		if(flg) std::cout << "NO\n";
		else std::cout << "YES\n";
	}
}

int main() {
	
	Solve();

	return 0;
}
posted @   Fire_Raku  阅读(13)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示