可惜多校联合第一次就错过了。。。
这是后来做的~
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个范围内的最小值的时候,没必要对于每一种情况都一一列举,只需要跑一次就可以了~