A1638 合并数字


合并数字

题目大意

蒜头君得到了 nn 个数,他想对这些数进行下面这样的操作,选出最左边的相邻的差的绝对值为 11 的两个数,只保留较小的数,删去较大的数,直到没有两个相邻的差的绝对值为 11 的数,问最多可以进行多少次这样的操作?

输入格式

输入第一行为一个整数 n(1 ≤ \leq n ≤ \leq 10 5 ^5 5) 表示数字的总数
第二行为 nn 个整数 x 1 _1 1,x 2 _2 2,…,x n _n n(0 ≤ \leq x_i ≤ \leq 10 9 ^9 9)表示这些数。

输出格式

输出一行,为一个整数,表示蒜头君最多可以进行多少次这样的操作。

输入复制

4
1 2 0 1

样例输出

3

解题思路

数组模拟栈,最左边最开始理解错误,后来发现就是用栈,当前的数比栈顶数小,栈顶元素出栈,这个数入栈,入栈的元素再与栈中紧邻的元素比较,若是比栈下面的元素大且大1,栈顶元素出栈,直到不满足题意,如果栈顶元素比挨着的元素小且小1,那么保留栈顶元素,出栈,更新栈顶元素。最后入栈的条件就是不满足上述所有情况就入栈,最后栈中的元素个数就是不能操作的步数,操作数就是 n - 栈中的元素。

AC代码

#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#define rep(i,a,b) for(auto i=a;i<=b;++i)
#define per(i,a,b) for(auto i=a;i>=b;--i)
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int a[maxn],b[maxn];
string s;
int main()
{
    std::ios::sync_with_stdio(false),cin.tie(0);
    int n,x;
    cin>>n>>x;
    int res=0,idx=1;
    b[idx]=x;
    rep(i,2,n){
        cin>>a[i];
        if(b[idx]==a[i]+1){
            while(b[idx]==a[i]+1&&idx) --idx;
            b[++idx]=a[i];

            if(b[idx]==b[idx-1]+1) --idx;
            else if(b[idx]+1==b[idx-1]){
                int t=b[idx];
                --idx;
                b[idx]=t;
            }
        }
       else if(b[idx]+1!=a[i] && b[idx]!=a[i]+1)
            b[++idx]=a[i];
    }
   // rep(i,1,idx) cout<<b[i]<<" ";cout<<endl;
    cout<<n-idx<<'\n';
    return 0;
}

总结

今天不想做题,犯困,cf有些题就是想不通,现在坚持小号打codeforces(我姐姐的邮箱注册的cf 账号)不知道今年CCPC会是什么情况(估计没名额吧),好好刷Kuangbin专题,好好补题,其余什么的不想去想了,我希望能遇到一起刷题的吧,而不是所谓的搜题抄题AC,因为真正比赛不会出原题,最主要的是思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸愉聊信奥

谢谢亲的支持,我会继续努力啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值