当然像蒟蒻的我会在这个题上模拟一边伪代码,如果程序没有跳出的话,说明当前 cur 没有跑遍 s 数组就已经变成了负数,所以在下一次循环中 ,也就是 cur+1 的值仍能跑到当时 cur 跑到的地方,我们记下 cur 跑到的位置,以及在 cur 遍历数组过程中 res 增长的值 即可,思想类似于剪枝
const int N=1e6+5;
int n,m,t;
int i,j,k;
char s[N];
int main()
{
IOS;
rush(){
cin>>s+1;
int len = strlen(s+1);
ll res = 0; //保存答案,注意数据类型
int pos = 1; //上一次的位置
int val = 0; //记录上一次 cur 跳出时的值,应该是 -1
int tmp = 0; //记录 cur 遍历过程中,res 的增长值
for(int init=0;init<=inf;init++)
{
int cur = val;
bool ok = true;
//debug(tmp);
res += tmp;
//tmp=0;
for (int i=pos;i<=(len);i++){
tmp = tmp + 1;
if (s[i] == '+')
cur = cur + 1;
else
cur = cur - 1;
//debug(cur);
if (cur < 0){
pos = i+1; //直接从下一个位置开始遍历
val = cur+1;
//cout<<-1<<endl;
//debug(pos);debug(val);
ok = false;
break;
}
}
if (ok) break;
}
cout<<res+tmp<<endl; //最后遍历完成 tmp==len
}
//PAUSE;
return 0;
}
更简洁的 AC 代码:
const int N=1e6+5;
int n,m,t;
int i,j,k;
char s[N];
int main()
{
//IOS;
rush(){
cin>>s+1;
int len=strlen(s+1);
ll res=0,cur=0;
for(i=1;i<=len;i++){
if(s[i]=='+') cur++;
else cur--;
if(cur<0) res+=i,cur=0;
}
cout<<res+len<<endl;
}
//PAUSE;
return 0;
}