萌新求助
查看原帖
萌新求助
126582
Scintilla楼主2021/6/25 16:04

我的代码和题解主体思路一样但是细节不同,现在一直是只有最后一组 WA,小范围数据拍了几千组无果,最后一组数据又下不下来,有哪位好心人愿意提供一下数据或坑点或帮我 debug 一下吗?谢谢!

#include <bits/stdc++.h>

using namespace std;

#define il inline
#define re register
#define rep(i, s, e) for (re int i = s; i <= e; ++i)
#define drep(i, s, e) for (re int i = s; i >= e; --i)
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)

const int N = 4000 + 10;
const int K = 20000 + 10;

il int read() {
    int x = 0; bool f = true; char c = getchar();
    while (!isdigit(c)) {if (c == '-') f = false; c = getchar();}
    while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
    return f ? x : -x;
}

int z[K];
il void Z(char *s, int n) {
    rep(i, 1, n) z[i] = 0;
    z[1] = n;
    for (int i = 2, l = 0, r = 0; i <= n; ++i) {
        if (i <= r) z[i] = min(z[i - l + 1], r - i + 1);
        while (i + z[i] <= n && s[i + z[i]] == s[z[i] + 1]) ++z[i];
        if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
    }
}

int p[N];
il void exkmp(char *s, int n, char *t, int m) {
    Z(t, m);
    rep(i, 1, n) p[i] = 0;
    for (int i = 1, l = 0, r = 0; i <= n; ++i) {
        if (i <= r) p[i] = min(z[i - l + 1], r - i + 1);
        while (i + p[i] <= n && p[i] < m && s[i + p[i]] == t[p[i] + 1]) ++p[i];
        if (i + p[i] - 1 > r) l = i, r = i + p[i] - 1;
    }
}

int n, k, len[N], mlen[N];
char s[N][K], mth[N][K], tmp[K];
bitset <K> P[N], S[N], can[N], ret[N];

int main() {
    file(data);
    n = read(), k = read();
    rep(i, 1, n) scanf("%s", s[i] + 1), len[i] = strlen(s[i] + 1);
    P[0][0] = 1, S[n + 1][0] = 1;
    rep(i, 1, n) P[i] = P[i - 1] | (P[i - 1] << len[i]);
    drep(i, n, 1) S[i] = S[i + 1] | (S[i + 1] << len[i]);
    rep(i, 1, n) rep(j, 0, k) can[i][j] = P[i][j] & S[i + 1][k - j];
    ret[0][0] = 1;
    rep(i, 1, n) {
        mlen[i] = mlen[i - 1];
        rep(j, 1, mlen[i - 1]) tmp[j] = mth[i][j] = mth[i - 1][j];
        rep(j, 1, len[i]) tmp[mlen[i - 1] + j] = s[i][j];
        exkmp(tmp, mlen[i - 1] + len[i], s[i], len[i]);
	   	int pos = -1;
        rep(j, 0, mlen[i - 1]) {
            if (!ret[i - 1][j] || !can[i][j + len[i]]) continue;
            if (p[j + 1] < len[i] && (can[i][mlen[i - 1] + len[i]] || j + p[j + 1] < mlen[i - 1]) && tmp[j + 1 + p[j + 1]] < s[i][p[j + 1] + 1]) continue;
			if (p[j + 1] == len[i] && j + len[i] <= mlen[i - 1]) continue;
			if (p[j + 1] == len[i]) {
				if (pos == -1 || p[pos + 1] == len[i]) pos = j;
				else if (tmp[pos + 1 + p[pos + 1]] < s[i][p[pos + 1] + 1]) pos = j;
				continue;
			}
            if (pos == -1) { pos = j; continue; }
			if (pos + p[pos + 1] < j + p[j + 1]) {
				if (tmp[pos + 1 + p[pos + 1]] < s[i][p[pos + 1] + 1]) pos = j;
				continue;
			}
			else if (pos + p[pos + 1] == j + p[j + 1]) {
				int d = j - pos, l = z[d + 1];
				if (l < len[i] - d) {
					if (s[i][d + 1 + l] > s[i][l + 1]) pos = j;
                    continue;
				}
				else {
					bool flag = true;
					rep(rnm, len[i] - d + 1, len[i]) {
						if (!can[i][mlen[i - 1] + len[i]] && j + rnm - 1 > mlen[i - 1]) break;
						if (s[i][rnm] < tmp[j + rnm - 1]) break;
						else if (s[i][rnm] > tmp[j + rnm - 1]) { flag = false; break; }
					}
					if (flag) pos = j;
                    continue;
				}
			}
			else {
				if (tmp[j + 1 + p[j + 1]] > s[i][p[j + 1] + 1]) pos = j;
				continue;
			}
        }
        if (pos == -1) {
			mlen[i] = mlen[i - 1], ret[i] = ret[i - 1];
			rep(j, 1, mlen[i]) mth[i][j] = mth[i - 1][j];
			rep(j, 0, mlen[i] - len[i]) if (ret[i - 1][j] && p[j + 1] == len[i]) ret[i][j + len[i]] = true;
		}
		else {
			mlen[i] = pos + len[i], ret[i][mlen[i]] = true;
			rep(j, 1, pos) mth[i][j] = mth[i - 1][j];
			rep(j, 1, len[i]) mth[i][pos + j] = s[i][j];
			rep(j, 0, pos) if (ret[i - 1][j]) ret[i][j] = true;
            rep(j, 1, len[i]) {
                if (pos + j > mlen[i - 1] || mth[i - 1][pos + j] != s[i][j]) break;
                if (ret[i - 1][pos + j]) ret[i][pos + j] = true;
            }
			rep(j, 0, pos) {
                if (!ret[i - 1][j]) continue;
                if (j + len[i] <= pos) {
                    if (p[j + 1] == len[i]) ret[i][j + len[i]] = true;
                }
                else {
                    int d = pos - j;
                    if (p[j + 1] >= d && z[d + 1] == len[i] - d) ret[i][j + len[i]] = true;
                }
            }
		}
    }
    rep(i, 1, k) printf("%c", mth[n][i]);
    puts("");
    return 0;
}

2021/6/25 16:04
加载中...