PNRPC 2017-2018 Gym101615I

 

题意

给两个编辑序列,描述删除一个位置上的字符,在某个位置之前插入一个字符,问这两个编辑序列是否对于任意足够长的文本都等价

做法

转化成另一种描述方式,即原串某位置上的字符被删除了,以及在编辑后的串中某位置上的字符是插入的,然后比较这种描述是否相同即可。

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

typedef long long LL;

struct E {
    LL pos;
    string ins;
    E(LL pos, string ins):pos(pos), ins(ins) {
    }
    bool operator < (const E&rhs) const {
        return pos < rhs.pos;
    }
};

char ope[3000];
void solve(vector<E>&r) {
    r.clear();
    LL pos;
    for (;;) {
        cin >> ope;
        if (ope[0] == 'E') break;
        if (ope[0] == 'D') {
            cin >> pos;
            bool ok = false;
            LL offset = 0;
            for (auto&&e : r) {
                int l = e.ins.length();
                LL r = offset + e.pos + l - 1;
                if (offset + e.pos > pos) break;
                if (r >= pos) {
                    e.ins.erase(pos - (offset + e.pos), 1);
                    ok = true;
                    break;
                } else {
                    offset += (int)e.ins.length() - 1;
                }
            }
            if (!ok) {
                r.push_back(E(pos - offset, ""));
            }
        } else {
            cin >> pos >> ope;
            bool ok = false;
            LL offset = 0;
            for (auto&&e : r) {
                int l = e.ins.length();
                LL r = offset + e.pos + l - 1;
                if (offset + e.pos > pos) break;
                if (r >= pos) {
                    e.ins.insert(pos - (offset + e.pos), ope);
                    ok = true;
                    break;
                } else {
                    offset += (int)e.ins.length() - 1;
                }
            }
            if (!ok) {
                r.push_back(E(pos - offset, string(ope) + '+'));
            }
        }
        sort(r.begin(), r.end());
    }
}

typedef vector<E>::iterator iter;
struct F {
    LL pos;
    char c;
    bool operator < (const F&rhs) const {
        return pos < rhs.pos || (pos == rhs.pos && c < rhs.c);
    }
};

void seq(vector<E>&a, vector<F>&A) {
    A.clear();
    LL offset = 0;
    for (auto&&v : a) {
        int l = v.ins.length();
        bool ok = false;
        int pos = v.pos + offset;
        for (auto&&c : v.ins) {
            if (c == '+') {
                ok = true;
            } else
                A.push_back((F){v.pos + offset++, c});
        }
        if (!ok) {
            A.push_back((F){v.pos, '-'});
            --offset;
        }
    }
}
vector<F> A, B;
bool same(vector<E>&a, vector<E>&b) {
    seq(a, A);
    seq(b, B);

    sort(A.begin(), A.end());
    sort(B.begin(), B.end());

    if (A.size() != B.size()) return 0;
    
    for (int i = 0; i < (int)A.size(); ++i) {
        if (A[i].pos != B[i].pos) return 0;
        if (A[i].c != B[i].c) return 0;
    }
    return 1;
}

vector<E> a, b;
int main() {
#ifdef lol
    freopen("I.in", "r", stdin);
    freopen("I.out", "w", stdout);
#endif

    solve(a);
    solve(b);
    cout << (!same(a, b)) << endl;

    return 0;
}

 

posted @ 2017-11-20 16:39  ichneumon  阅读(281)  评论(0编辑  收藏  举报