多校联合 03 15 A

来源:互联网 发布:尤克里里怎么调音软件 编辑:程序博客网 时间:2024/06/05 07:51

可惜多校联合第一次就错过了。。。

这是后来做的~

 

ProblemA. Non-negativePartialSums
TimeLimit:2000ms Memory:65536kb
Description
Youaregivenasequenceofnnumbersa0,....,an-1.Acyclicshiftbykpositions
(0≤k≤n-1)resultsin the followingsequence: ak,ak+1,...,an-1,a0,a1,...,ak-1
. Howmanyof
the ncyclicshiftssatisfythe conditionthat the sumofthe first i numbersis greater
thanorequaltozeroforalliwith1≤i≤n?
Input
Eachtestcaseconsistsoftwolines.Thefirstcontainsthenumbern(1≤n≤10
6
),the
number if integers in the sequence. The second contains n integers
a0,...,an-1(-1000≤ai≤1000)representingthe sequenceofnumbers.Theinput willfinish
withalinecontaining0.
Output
Foreachtest case,printoneline withthe numberofcyclicshifts ofthe given
sequencewhichsatisfytheconditionstatedabove.
Sample
INPUT OUTPUT
3
2 2 1
3
-1 1 1
1
-1
0
3
2
0

 

 

这道题题意:n个数字组成一个环,求从环的不同点出发,前1~n的和不小于0的个数。

 

思路:思路其实只要想到了,就不难~

 

把每个数组分成2n,先求前缀和,然后不论是从哪一个从发,只要这个点以后的n个点中的前缀和的最小值大于该点前缀和的最小值,那么在这一个点上,就成立。

 

我先按照这个思路,码了一下:

 

#include<iostream>#include<fstream>using namespace std;int a[2000005];long long sum[2000005];int main(){    int n;    freopen("A.in","r",stdin);    freopen("A.out","w",stdout);    while(cin>>n){        if(n==0)            break;        memset(sum,0,sizeof(sum));        for(int i=0;i<n;i++){                cin>>a[i];                a[i+n]=a[i];                }        sum[0]=a[0];        for(int j=1;j<2*n;j++){                sum[j]=sum[j-1]+a[j];                }        int times=0;        long long temp1;        for(int k=0;k<n;k++){                if(a[k]<0)                    continue;                if(k==0)                    temp1=0;                else                    temp1=sum[k-1];                long long minn=sum[k];                for(int g=k;g<k+n;g++){                        if(minn>sum[g]){                             minn=sum[g];                             }                             }                if(temp1<=minn)                        times++;                        }        cout<<times<<endl;        }    return 0;}


结果倒是正确,只是。。。

 

10^6啊。。。2s跑不动啊。。。。

 

于是,意识到算法好不够好

 

翻了一下标程,发现竟然要用队列!!!

 

果然用队列要简单很多~主要是在求n个范围内的最小值的时候,没必要对于每一种情况都一一列举,只需要跑一次就可以了~

原创粉丝点击