• 洛谷 P2629 好消息,坏消息


    题目描述

    uim在公司里面当秘书,现在有n条消息要告知老板。每条消息有一个好坏度,这会影响老板的心情。告知完一条消息后,老板的心情等于之前老板的心情加上这条消息的好坏度。最开始老板的心情是0,一旦老板心情到了0以下就会勃然大怒,炒了uim的鱿鱼。

    uim为了不被炒,知道了了这些消息(已经按时间的发生顺序进行了排列)的好坏度,希望研究如何不让老板发怒。

    uim必须按照时间的发生顺序逐条将消息告知给老板。不过uim可以使用一种叫“倒叙”的手法,例如有n条消息,小a可以从k,k+1,k+2...n,1,2...k-1这种顺序通报。

    他希望知道,有多少个k,从k开始通报到n然后从1通报到k-1可以让老板不发怒。

    输入输出格式

    输入格式:

    第一行一个整数n(1 <= n <= 10^6),表示有n个消息。

    第二行n个整数,按时间顺序给出第i条消息的好坏度Ai(-1000 <= Ai <= 1000)

    输出格式:

    一行一个整数,表示可行的方案个数。

    方法::根据某巨佬的吞噬算法写的,以下为转载自   MARSHALBEN的博客

    *****************************************************

    基础思路

    简单看来这就是一个环,选能走下来的位数和一直不小于0的数。。。样例和没有没区别。然而环,单调队列神马的都太复杂了,现在请参考吞噬算法——
    产生随机数 7,1,-5,2,-3(n=5) 
    首先,从第一位开始扫到第一个负数-5,然后用-5 吃掉前一个数1 ,于是变成了7, -4 ,2,-3 
    看来,一个1 满足不了-5 的胃口,于是接着往下吃 3 ,2,-3 . 
    呃,-4 撑死了……那就接着往下揍,找到了-3 ,-3 吃了2 ,变成3,-1,再往前吃,就成了2,好了,只剩下正数了,于是输出正数的个数 1。 

    通俗解释

    那么,通俗点说呢,首先找到-5,要想成立,-5前面的和必须比0大,于是-5必须在1后面。同理,7,1,-5这个顺序不能打乱。于是推到最后,就行了。

    栈实现

    这里是用栈来实现

    这里写图片描述

    另一种解释

    然后另一组随机数据-3,5,1,2 怎么办? 
    依然很简单。先将a【1】a【4】吞噬了(a【i】,a【n】) 然后n– 直到a【1】 再push

    这里写图片描述

    **********************************************************************************************

    所以代码就这样了

    /*竟然起名叫做吞噬算法,据说是烟台一中自创的*/
    /*因为我们不能有小于0的值,所以我们在入栈时如果小于零,我们要向前吞噬,直到大于零*/
    /*最后数一下栈中有几个数就行了*/
    #include<cstdio>
    #include<algorithm>
    #define maxn 1000001
    using namespace std;
    int stack[maxn];
    int note[maxn]; 
    int top=0;
    int read()
    {
        int now=0;
        int f=1;
        char c=getchar();
        while(c>'9'||c<'0')
        {
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9')
        {
            now*=10;
            now+=c-'0';
            c=getchar();
        }
        return now*f;
    }
    int main()
    {
        int n=read();
        for(int i=1;i<=n;i++)
        {
            note[i]=read();
        }
        for(int i=1;i<=n;i++)
        {
            top++;
            stack[top]=note[i];
            while(stack[top]<0&&top>1)
            {
                top--;
                stack[top]+=stack[top+1];
                stack[top+1]=0; 
            }
            while(stack[top]<0)
            {
                stack[top]+=note[n];
                n--;
                if(n<i)
                {
                    printf("0");/*全找完了还是小肯定没办法了*/ 
                    return 0;
                }
            }
        }
        printf("%d",top); 
        return 0;
    }
  • 相关阅读:
    随题而学(二)多维数组转一维数组
    随题而学(一)
    谁能破解“无法定位程序输入点ucrtbase.abort与动态链接库api-ms-win-crt-runtime-l1-1-0.dll上”
    虚拟机8—tools安装失败
    win7介绍
    win xp安装
    Linux正则表达式,grep总结,sed用法
    Linux将用户添加到组的指令
    xxx is not in the sudoers file.This incident will be reported.的解决方法
    69-70连接查询
  • 原文地址:https://www.cnblogs.com/luoyibujue/p/6884150.html
Copyright © 2020-2023  润新知