NWERC-2018 Equality Control 语法树 大模拟

NWERC-2018 Equality Control 语法树 大模拟

题意

现给出表达式,表达式中包含([],contract,sort,shuffle)。即序列,拼接,排序,随机

给出两个表达式,问这两个表达式的序列的出现概率相同。

input

concat(shuffle([1,2]),shuffle([1,2]))
shuffle([1,2,1,2])

output

not equal

input

sorted(concat([3,2,1],[4,5,6]))
[1,2,3,4,5,6]

output

equal

input

concat(sorted([4,3,2,1]),shuffle([1]))
concat(concat([1,2,3],shuffle([4])),sorted([1]))

output

equal

分析

为了使问题得到简化,发现几处性质:

  • shuffle中的数字如果都相同则这个shuffle没有意义
  • contract可以无视
  • 若出现sort和shuffle嵌套出现,外层的才发挥作用
  • 判定是否等价的两个条件:所有shuffle的存在区间相等,其他数位置大小都相等

代码

此题实现有点复杂,贴的大神代码,用来学习

typedef pair<vector<int>, vector<pii> > ret;

ret get(string s) {
    int n = s.length();
    vector<int> a, sum(n, -1);
    for (int i = 0, j ; i < n; i = j + 1) {
        j = i;
        if (s[i] >= '0' && s[i] <= '9') {
            int x = 0;
            while (j < n && s[j] >= '0' && s[j] <= '9') {
                x = x * 10 + s[j] - '0';
                j++;
            }
            sum[j - 1] = a.size();
            a.push_back(x);
        }
    }
    vector<pii> seg;
    for (int i = 0, j; i < n; i = j + 1) {
        j = i;
        if (s[i] != 's') continue;
        int cnt = 0;
        while (j < n && (s[j] < '0' || s[j] > '9')) {
            if (s[j] == '(')  cnt++;
            j++;
        }
        int l = INF, r = -1;
        while (j < n && cnt > 0) {
            if (s[j] == '(') cnt++;
            if (s[j] == ')') cnt--;
            if (sum[j] != -1) {
                l = min(l, sum[j]);
                r = max(r, sum[j]);
            }
            j++;
        }
        if (l > r) continue;
        sort(a.begin() + l, a.begin() + r + 1);
        if (s[i + 1] == 'h' && a[l] != a[r])
            seg.push_back(make_pair(l, r));
    }
    return make_pair(a, seg);
}

int main() {
    string s1, s2;
    cin >> s1 >> s2;
    ret A = get(s1);
    ret B = get(s2);
    if (A == B) puts("equal");
    else puts("not equal");
}
原文地址:https://www.cnblogs.com/hznumqf/p/13760537.html