Codeforces Global Round 9 - C.Element Extermination (栈,贪心)

题目传送
题意:
给你n大小的数组排列,现在如果有俩个连续的数满足ai < ai+1,那么你可以删去其中的一个数,现在问:在进行上述操作后,是否有可能使得数组元素为1

第一思路:
分情况贪心:

1.如果栈为空,那么直接把这个元素收入栈中

2.如果现在输入的元素小于栈顶元素,那么执行不了删除操作,把现在输入的元素入栈

3.如果现在输入的元素大于栈顶元素(满足操作删除条件)

(1)如果现在的栈中元素个数为1,那么我们直接删除现在输出的元素(因为现在栈中的元素比较小,我们要把小的让出来,使其尽可能的去匹配后面的元素)

(2)如果现在的栈中元素个数不为1,那么我们现在删除栈顶元素,把现在输入的数入栈(因为栈中元素个数不为1,那么说明现在栈中的元素不满足删除条件,例 : 现在栈中元素为 8 5 ,现在输入的元素为9,那么我们肯定是要把现在可以删的元素的最大值让出来,使其尽可能的去和栈中的其他元素匹配)

4.在输入完后,判断现在的栈的元素个数是否为1,如果是,则YES,否则NO

第二思路
就是第一个数比最后一个数小就能输出YES

原理:
也是根据上面来推的:

如果a1 < a2,那么我们直接删除a2.

否则的话,我们知道a1 < an的,那么又因为现在a2 < a1 < an,那么肯定a2也能和an匹配。
那么只有这俩种情况,俩种情况都能删下去,那么得证成立这里就不贴代码啦

AC代码

#include <bits/stdc++.h>
inline long long read(){char c = getchar();long long x = 0,s = 1;
while(c < '0' || c > '9') {if(c == '-') s = -1;c = getchar();}
while(c >= '0' && c <= '9') {x = x*10 + c -'0';c = getchar();}
return x*s;}
using namespace std;
#define NewNode (TreeNode *)malloc(sizeof(TreeNode))
#define Mem(a,b) memset(a,b,sizeof(a))
#define lowbit(x) (x)&(-x)
const int N = 1e5 + 10;
const long long INFINF = 0x7f7f7f7f7f7f7f;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
const int mod = 1e9+7;
const double II = acos(-1);
const double PP = (II*1.0)/(180.00);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> piil;
signed main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    //    freopen("input.txt","r",stdin);
    //    freopen("output.txt","w",stdout);
    int t,n,num;
    cin >> t;
    while(t--)
    {
        cin >> n;
        stack<int>s;
        while(n--)
        {
            cin >> num;
            if(s.empty())//如果栈为空,加入元素到栈中
                s.push(num);
            else if(s.top() < num)//如果满足删除条件
            {
                if(s.size() == 1) continue;//如果现在的栈中元素个数为1,那么把更小的数让出来
                else s.push(num);//否则的话我们先入栈
                while(1)//开始匹配掉栈中满足删除条件的元素
                {
                    int a = s.top();s.pop();
                    int b = s.top();s.pop();//取出栈中最前面的俩个元素
                    if(a > b)//如果满足删除条件
                    {
                        if(s.size() >= 1) s.push(a);//如果栈中还有元素,那么我们必须去尽最大可能的去匹配掉他,所以让出最大的那个元素出来
                        else s.push(b);//如果栈中没有元素了,那么我们就让出最小的数出来去尽量匹配后面的元素
                    }
                    else//如果不满足删除条件了那么再次入栈,注意入栈顺序哈
                    {
                        s.push(b);s.push(a);
                        break;
                    }
                    if(s.size() == 1) break;//如果栈中只有一个元素了,直接break
                }
            }
            else //如果不满足删除条件,那么入栈
                s.push(num);
        }
        s.size() == 1 ? cout << "YES" << endl : cout << "NO" << endl;//最后判断
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值