UVa1491/LA5693 Compress the String

该博客主要讨论了一种在线字符串压缩问题的解决方案,通过深度优先搜索(DFS)策略来判断一个长字符串是否能被分解为多个短字符串。文章详细分析了题意、解题思路,并给出了AC代码实现,涉及字符串处理和递归算法的应用。
摘要由CSDN通过智能技术生成

题目链接

        Online Judge

题意

        给出短字符串个数n,每个短字符串的长度上限L(1),L(2),...,L(n),一个长字符串s,问长字符串s是否可以压缩成n个字符串。

分析

        dfs

AC代码

#include <iostream>
#include <cstring>
using namespace std;

#define M 510
#define N 4
char s[M]; short a[N-1][N], b[N*N*N], l[N], ll[N], c[N], f[N], ff[N], m, n, t, cc;

void expand(short i = 0) {
    for (short j=0; j<ll[i]; ++j) {
        if (a[i][j]) {
            short k = a[i][j];
            if (f[k] < 0) f[k] = t;
            if (k == n-1) {
                b[t++] = 1; ++cc;
            } else expand(k);
        } else b[t++] = 0;
    }
}

bool check(short i, short l) {
    for (short j=0; j<ll[i]; ++j) {
        if (a[i][j]) {
            short k = a[i][j], tt = t;
            if (k == n-1) t += l;
            else if (!check(k, l)) return false;
            for (short p=tt; p<t; ++p) if (s[p] != s[p+ff[k]-tt]) return false;
        } else ++t;
    }
    return true;
}

bool check(short l) {
    for (short i=0, j=0; i<t; ++i) {
        for (short k=1; k<n; ++k) if (f[k] == i) ff[k] = j;
        b[i] ? j += l : ++j;
    }
    t = 0;
    return check(0, l);
}

bool dfs(short i = 0, short p = 0) {
    if (i == n-1) {
        for (short i=1; i<n; ++i) f[i] = -1;
        t = cc = 0;
        expand();
        for (short ll=2; ll<=l[i]; ++ll) if (t+cc*(ll-1) == m && check(ll)) return true;
        return false;
    }
    if (i>0 && (!c[i] || ll[i])) return dfs(i+1);
    for (short j=i; j<n; ++j) {
        ++c[a[i][p] = j==i ? 0 : j];
        if (p+1<l[i] && dfs(i, p+1)) return true;
        if (i == 0) for (short k=1; k<n; ++k) ll[k] = 0;
        ll[i] = p+1;
        if (dfs(i+1)) return true;
        --c[a[i][p]];
    }
    return false;
}

bool solve() {
    t = 1;
    for (short i=0; i<n; ++i) {
        cin >> l[i]; t *= l[i];
        if (l[i] == 1) --i, --n;
    }
    cin >> s;
    m = strlen(s);
    if (m > t) return false;
    if (n < 2) return true;
    for (short i=0; i<n; ++i) if (m <= l[i]) return true;
    for (short i=1; i<n; ++i) c[i] = 0;
    return dfs();
}

int main() {
    while (cin >> n) cout << (solve() ? "Yes" : "No") << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值