洛谷 P2629 好消息,坏消息
Posted fastle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 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; }
以上是关于洛谷 P2629 好消息,坏消息的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段