C. Queries for the Array - 思维

C. Queries for the Array - 思维_第1张图片C. Queries for the Array - 思维_第2张图片分析:

        分析出现矛盾的地方,也就是可能遇到0,并且已有字符串的长度小于等于1,另一种情况就是,遇到了1并且已有字符串不是排好序的,或者遇到了0已有字符串是排好序的,那么可以遍历字符串,统计排好序的最大前缀,没有排好序的最小前缀,那么最小没排序的前缀必须大于最大排好序的区间,否则就说明二者矛盾,那么在遍历过程中先单独看每一种情况应该有什么效果,一旦s[i] == '+',那么就让字符串的长度加一,如果s[i] == '-',那么就将字符串的长度减一,同时由于字符串长度减一,如果最大的排好序的长度比当前长度大,说明最大排好序的长度就变为更小的那一段了,所以要更新最大排好序的前缀,然后如果最小存在没排序的区间一旦比当前长度大,说明剩下的字符串可以是排好序的,因为没排好序最优情况下,只有最后一个元素是没有排序的,这种情况那么最小的没排序的长度也就变成了0,如果s[i] == '1',那么就需要更新一下最大排序的长度,如果s[i] == '0',首先判断一下长度是否大于1,如果小于等于1,那么表示矛盾,否则,表示没排序,如果没排序的最小前缀等于0(表示是排好序的),或者当前长度比没排好序的最小前缀要小,那么就需要更新一下没排序的最小前缀,在每次遍历处理完以上其中一种情况后,在进行评判条件是否矛盾,如果更新后的最小前缀小于等于最大的排好序的前缀,那么就表示每吨。

代码:

#include 

using namespace std;
using ll = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while(T --) {
        string s;
        cin >> s;
        int minn = 0, maxn = 0;
        int flag = 0;
        int cnt = 0;
        for(int i = 0; i < s.size(); i ++) {
            if(s[i] == '+') cnt ++;
            else if(s[i] == '-') {
                cnt --;
                maxn = min(maxn, cnt);
                if(minn > cnt) minn = 0;
            }
            else {
                if(s[i] == '1') {
                    maxn = max(maxn, cnt);
                }
                else {
                    if(cnt <= 1) {
                        flag = 1;
                        break;
                    }
                    if(minn == 0 || minn > cnt) minn = cnt;
                }
                if(minn <= maxn && minn != 0) {
                    flag = 1;
                    break;
                }
            }
        }
        if(flag) cout << "NO\n";
        else cout << "YES\n";
    }
}

你可能感兴趣的:(算法,c++,思维)