中南大学第十一届大学生程序设计竞赛-COJ1901-赏赐 OR 灾难

1901: 赏赐 OR 灾难

Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 2 Solved: 2
Description
大G南征北战终于打下了大片土地成立了G国,大G在开国大典上传召帮助自己南征北战的三大开国元勋小A,小B,小C进殿,并要赏赐三人大量宝物以显示天恩浩荡。大G在征服其他国家的时候抢夺了n箱宝物,他把这些箱子依次排列在三人面前,每个箱子里的宝物都有一个价值wi,大G令他们一人选取一个箱子作为奖励。 可是令大G万万没有想到的是,三人在私底下是存在竞争关系的,由于小B手上兵权强于小C,小C手上兵权强于小A。所以弱者总是担心自己领取的赏赐高于或等于强者会招来杀身之祸。所以他们三人总是会让小B先选取奖励之后,小C会在小B选择的右侧区域选择价值比小B小的奖励,而小A则会在小B选择的左侧区域选择价值比小B和小C都小的奖励。当然小B是个聪明人,他也会考虑到两人的想法选择对大家都有帮助的方案选取。请问是否存在这样一种选择方案让大家都不用担心会招致杀身之祸。如果存在输出“YES”,否则输出“NO”

Input
多组数据读入
每组数据第一行输入一个正整数n表示n箱宝物(n<=100000) 接下来一行输入n个正整数w1,w2,w3,…,wn表示n箱宝物的价值。(wi<=10000000) 题目保证所有数据n的总和不超过500000

Output
如果存要求的选择方案则输出“YES”,否则输出“NO”。

Sample Input
6
1 2 3 6 5 4
6
1 2 3 4 5 6
Sample Output
YES
NO
Hint
第一组数据中,小B可以先选择价值为6的箱子,小A可以在其左侧选择价值为2的箱子,小C可以在其右侧选择价值为5的箱子,这样大家都不用担心给自己招来杀身之祸。 第二组数据找不到任意一种选择方案,输出NO。

Source
中南大学第十一届大学生程序设计竞赛

Author
Forget_ever

题目大意:给出至多100000个数,要求判断是否可以找出三个数,满足 ai<ak<aj(i<j<k)
解题思路:预处理可求出i左边的最小价值Min[i-1]
用单调栈求出i右边小于 wi 的最大值
i从右向左扫一遍,找到满足的解就跳出
考查内容:算法优化,高级数据结构的使用

#include<iostream>
#include<string>
#include<cstdio>
#include<stack>
#include<algorithm>
using namespace std;
const int MAXN=100005;
const int INF=1000000000;
int Min[MAXN];//Min[i]表示前i个宝物中的最小价值
int w[MAXN];
stack<int> s;//单调栈

int main()
{
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n)
    {
        while(!s.empty()) s.pop();
        for(int i=1;i<=n;i++)
        {
            cin>>w[i];
            if(i==1) Min[i]=w[i];
            else Min[i]=min(Min[i-1],w[i]);
        }
        bool flag=false;
        s.push(w[n]);
        for(int i=n-1;i>=2;i--)
        {
            int a=Min[i-1];//i左边的最小值
            int c=-1;
            while(!s.empty()&&s.top()<w[i])
            {
                c=s.top();
                s.pop();
            }
            s.push(w[i]);
            if(c>a)
            {
                flag=true;
                break;
            }
        }
        if(flag) cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值