E – Three Substrings (巧妙思维、字符串匹配)

题目:传送门

题目:给你三个字符串a, b, c,他们都是字符串 s 的连续子串,字符 '?' 可以是任何字符,问字符串 s 的长度最小是多少。

1 <= len(a),len(b),len(c) <= 2000

 

思路:

很容易的可以想到一个贪心,就是,按照 a -> b -> c 这样的顺序去构造 s(共有六种方式,这里只列举一种),每次都尽可能的将 b 左移,将 c 左移, 这里有一个反例。

例如: a = ??c?, b = ac?a,c = ?b?a

按照上面的贪心策略,就是:

1、??c?(字符串a)

2、acca(字符串a和b合并,得到最优的ab)

3、accab?a(最优的ab和字符串c合并)

但是,最优的构造方式是:

1、??c?(字符串 a )

2、?ac?a(字符串 a 和 b 合并,得到 ab,b[0] 和 a[1] 对应)

3、?acbaa(字符串 ab 和字符串 c 合并,c[0] 和 ab[2] 对应)

所以这种贪心策略是错误的。

 

我们可以预处理字符串 a 和字符串 b 的匹配情况

ab[i]:表示,b 相对于 a 移动了 i 之后,是不是能匹配,例如我们假设 a = 12345, b = 2345,

那么 ab[1] 就是 a[1] 和 b[0] 对应,然后后面的也一 一对应是不是能匹配

12345

  2345

b[0] 和 a[1] 对应,b[1] 和 a[2] 对应,b[2] 和 a[3] 对应,b[3] 和 a[4] 对应,这样的对应,i - j 都是等于 1 的( i 是字符串 a 对应的下标,j 是字符串 b 对应的下标),所以只要有一个不等,就将 ab[1] 置为 1,表示不匹配。

按照同样的思路,预处理出 ac 和 bc

然后,就枚举 ab 的偏移量和 ac 的偏移量,判断是否能更新答案就行了。

复杂度 o(n^2)

 

#include <bits/stdc++.h>
#define LL long long
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF INT_MAX
#define inf LLONG_MAX
#define PI acos(-1)
using namespace std;

const int N = 2e4 + 5, up = 4000;

char a[N], b[N], c[N];
bool ab[N], ac[N], bc[N];

int main() {
    scanf("%s", a);
    scanf("%s", b);
    scanf("%s", c);
    int lena = strlen(a);
    int lenb = strlen(b);
    int lenc = strlen(c);

    rep(i, 0, lena - 1) rep(j, 0, lenb - 1) /// 预处理 ab
        if(!(a[i] == b[j] || a[i] == '?' || b[j] == '?')) ab[i - j + up] = 1;
    rep(i, 0, lena - 1) rep(j, 0, lenc - 1) /// 预处理 ac
        if(!(a[i] == c[j] || a[i] == '?' || c[j] == '?')) ac[i - j + up] = 1;
    rep(i, 0, lenb - 1) rep(j, 0, lenc - 1) /// 预处理 bc
        if(!(b[i] == c[j] || b[i] == '?' || c[j] == '?')) bc[i - j + up] = 1;

    int ans = INF;

    rep(i, -4000, 4000) rep(j, -4000, 4000)
        if(!ab[i + up] && !ac[j + up] && !bc[j - i + up]) { ///b相对于a偏移了i,c相对于i偏移了j,c相对于b偏移了j - i
            int L = min({0, i, j});
            int R = max({lena, lenb + i, lenc + j});
            ans = min(ans, R - L);
        }

    printf("%d\n", ans);

    return 0;
}

 

原文链接: https://www.cnblogs.com/Willems/p/12517857.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    E - Three Substrings (巧妙思维、字符串匹配)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/374361

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月3日 下午12:08
下一篇 2023年3月3日 下午12:08

相关推荐