CF1861C Queries for the Array

文章讲述了如何通过逻辑分析和动态规划解决一个关于数字序列操作的问题,涉及有序与无序判断,以及如何在给定条件下添加或删除数字以保持序列有序。

去洛谷看我的博客

思路

机翻害人,我还以为是 1 1 1 0 0 0 是对原序列排序,害得我比赛的时候都没对,恼。

首先,对于新加入的数字,我们可以先不确定是否有序,而是等到后续的 1 1 1 0 0 0 出现,再确定。

n u m num num 表示目前有多少数字,用 s o so so 表示确定有序的数字中最后一位的位置, n s o nso nso 表示确定无序的第一位数字的位置。

那么,我们可以分几种情况讨论:

  • 操作 0 0 0

    • 如果满足 s o = n u m so=num so=num,那么目前所有数字都一定排序,所以无解。
    • 如果满足 n u m < 2 num<2 num<2,按照题意,一定有序,所以无解。
    • 其他情况都可以满足条件,此时对于 [ s o + 1 , n u m ] [so+1,num] [so+1,num] 的数字中有一个数字是无序的就行,这里选择最后一位,因为最后一位更容易被删除,后续满足条件的可能性更大,即 n s o = n u m nso=num nso=num,注意:如果 n s o nso nso 本来就有值,代表有更靠前的无序数字,则无需更新 n s o nso nso
  • 操作 1 1 1

    • 如果此时 n s o > 1 nso>1 nso>1,代表前面有数字一定无序,所以无解。
    • 其他情况都可以满足条件,此时所有数都应该有序,即 s o = n u m so=num so=num
  • 操作 + + +,为了使后续操作满足条件可能性更大,所以选择添加未知数字,即仅 n u m + 1 num+1 num+1

  • 操作 − - ,先减 n u m num num,如果此时 n u m < s o num<so num<so,则也要把 s o so so 减一,如果此时 n u m < n s o num<nso num<nso,则代表无序的数字一定都被删了,所以更改 n s o nso nso 0 0 0

AC code

#include<bits/stdc++.h>
using namespace std;
int T,n,num,so,flag,nso;
char ch[200005];
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%s",ch+1),n=strlen(ch+1),nso=num=so=flag=0;
		for(int i=1;i<=n;++i)
		{
			if(ch[i]=='+') ++num;
			if(ch[i]=='-') --num,nso=(num<nso)?0:nso,so=min(so,num);
			if(ch[i]=='1')
			{
				if(nso){flag=1;break;}
				so=num;
			}
			if(ch[i]=='0')
			{
				if(num<2||so==num){flag=1;break;}
				if(!nso) nso=num;
			}
		}
		if(flag) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值