Codeforces 1373C


1373C. Pluses and Minuses


题意

给定仅由'+'和'-'组成的字符串

执行以下描述性代码

res = 0
for init = 0 to inf
    cur = init
    ok = true
    for i = 1 to |s|
        res = res + 1
        if s[i] == '+'
            cur = cur + 1
        else
            cur = cur - 1
        if cur < 0
            ok = false
            break
    if ok
        break

问最后res的值为多少


限制

Time limit per test: 2 seconds

Memory limit per test: 256 megabytes

1≤t≤1000

1≤|s|≤106

Σ|s|≤106




代码块的含义为


init从0开始依次递增,cur每次初始值即为init

然后遍历字符串,遇 + 使 cur+1,遇 - 使 cur-1

如果cur在过程中出现了小于0的情况,则退出遍历,进入下一次循环

如果cur在整个过程中没有出现小于0的情况,则退出循环


这是一个折线图,且相邻两个位置高度相差必为1

从左往右遍历这张图,一旦遇到某个点小于0,说明这一遍将会停在这个位置并跳出遍历

所以这一遍res增加的数值即为这个位置的数值

其后让起始点增加1(也表明整张图上移一格)继续判断


所以可以定义变量mn和cur初始值为0,遍历字符串

遇 + 使 cur+1,遇 - 使 cur-1

如果遍历中出现cur<mn的情况,说明上述代码块在init == -mn时会在该位置出现cur<0而退出遍历的情况

所以此时答案要加上当前位置,并让mn=cur(或者mn-1),表明init自增后继续执行

遍历结束后,答案还需加上字符串长度,表明退出代码块前执行的最后一次循环遍历了整个字符串




完整程序

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

char str[1000050];

void solve()
{
    scanf("%s",str+1);
    ll ans=0,mn=0,cur=0;
    int i;
    for(i=1;str[i]!='';i++)
    {
        if(str[i]=='+')
            cur++;
        else
        {
            cur--;
            if(cur<mn)
            {
                ans+=i; //加上该位置
                mn=cur;
            }
        }
    }
    ans+=i-1; //加上字符串长度
    printf("%d
",ans);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
        solve();
    return 0;
}

原文地址:https://www.cnblogs.com/stelayuri/p/13193748.html