序列I 题解

题目id:11050

题目描述

给定一个序列\(a=a_1,a_2,...,a_n\),有以下两种操作:

  • \(a_i=a_{i+1}\),则可将\(a_i\)\(a_{i+1}\)同时加\(1\)
  • \(a_i+2\)

解题思路

第一眼莫名想到了二分(狗头)
括号匹配大家都做过吧,这题思路其实也差不多,都用栈解决。

  • 操作\(1\)可以改变相邻且相同的两个数字的奇偶性(奇数\(+1=\)偶数,偶数\(+1=\)奇数)
  • 操作二不会改变数字的奇偶性

那么我们可以先执行操作一,直到所有数都是奇数\(/\)都是偶数为止,再通过操作\(2\)就一定可以转换成相同的。
那么这和括号匹配有什么关系呢?
我们先求出每一个数是否是奇数(用\(1/0\)表示),如果当时栈顶元素与求得的值相同且栈不为空,则将栈顶元素出栈(这两个数可以转化为相同类型的数(奇数\(/\)偶数))
最后,如果栈里元素个数>\(1\)说明剩下的元素无法转化为相同类型的数(奇数\(/\)偶数),输出\(NO\)
如果\(\leq 1\),则输出\(YES\)
是不是和括号匹配很像?
括号匹配是每次取出括号,这题是每次取出\(1/0\)比较而已。

AC Code

#include<bits/stdc++.h>
#define N 1000007
#define INF 1e18
#define MOD 998244353
#define LL long long
#define pb push_back
#define lb long double
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define IOS ios::sync_with_stdio(0),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
LL T,n,a[N];
int main()
{
    IOS;
    cin>>T;
    while(T--)
    {
        stack<int>s;
        cin>>n;
        for(LL i=1,a;i<=n;++i)
        {
            cin>>a;
            if(!s.empty()&&s.top()==(a&1))
                s.pop();
            else  
                s.push(a&1);
        }
        if((LL)(s.size())>1)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}
posted @ 2024-08-06 16:39  Firra3500  阅读(20)  评论(0编辑  收藏  举报