题意:给你一列数,他能够旋转,如果对于其中的一个状态,如果他的任意的前i个数之和(n>=i>=1),那么就称此状态为合法的状态,现在对于任意输入的一列数,问一共有多少个合法的状态?
思路:我们观察一下数据的范围就可以很容易的判定O(N^2)的枚举是不行的,那么我们必须找出最坏是:O(NlogN)的算法。
最终我还是没有想出好的算法,还是在同志的提醒下知道了用单调队列去解。比赛是我也想到过单调队列,但是只写过一次,因此由于掌握不熟而错过了一次很好的机会。
现在我先重申一下思路,代码改日补上:
看了一下别人的代码,我傻眼了。。。。。。。原来那么简单的题啊,但是怎么就sb了吗?
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define re(i,n) for(int i=0;i<n;i++)
int num[2000005];
bool hash[2000005];
int main(){
int n ;
while(cin>>n && n){
for(int i=0;i<n;i++) {scanf("%d",&num[i]); hash[i] = 1;}
for(int i=n;i<2*n;i++) num[i]= num[i-n];
long long sum = 0;
for(int i=n*2-1;i>=0;i--){
if(sum<0) {sum+=num[i];
if(sum<0) hash[i]=0;
}
else if(num[i]<0) sum=num[i], hash[i]=0;
}
// re(i,n) cout<<hash[i]<<" "; cout<<endl;
int ans =0;
for(int i=0;i<n;i++) if(hash[i]) ans ++;
cout<<ans<<endl;
}
}