阅读程序(第一题):字符串哈希 + 二分求最长公共子串

yq675315 组合题 共 个子题

阅读下面程序,完成后面的判断题和单选题。判断题正确填 A,错误填 B。程序每次读入两行不含空格的字符串(均由小写字母组成,长度不超过 100000)。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>

typedef unsigned long long ull;
const int MAXN = 100005;
int n, m;
char A[MAXN], B[MAXN];
ull hA[MAXN], hB[MAXN], pw[MAXN];
const ull BASE = 131;

int check(int L) {
    std::vector<ull> v;
    for (int i = 0; i + L <= n; ++i)
        v.push_back(hA[i + L] - hA[i] * pw[L]);
    std::sort(v.begin(), v.end());
    for (int i = 0; i + L <= m; ++i) {
        ull t = hB[i + L] - hB[i] * pw[L];
        if (std::binary_search(v.begin(), v.end(), t))
            return 1;
    }
    return 0;
}

int main() {
    scanf("%s", A);
    scanf("%s", B);
    n = (int)strlen(A);
    m = (int)strlen(B);
    pw[0] = 1;
    for (int i = 1; i <= n || i <= m; ++i)
        pw[i] = pw[i - 1] * BASE;
    for (int i = 0; i < n; ++i)
        hA[i + 1] = hA[i] * BASE + A[i];
    for (int i = 0; i < m; ++i)
        hB[i + 1] = hB[i] * BASE + B[i];
    int l = 0, r = (n < m ? n : m);
    while (l < r) {
        int mid = (l + r + 1) / 2;
        if (check(mid))
            l = mid;
        else
            r = mid - 1;
    }
    printf("%d\n", l);
    return 0;
}

子题 判断题

判断题:程序输出的是两个输入字符串的最长公共子序列(不要求连续)的长度。( )

A

正确

B

错误

子题 判断题

判断题:当两行输入分别为 abcabcde 与 bcdeabc 时,程序的输出为 3。( )

A

正确

B

错误

子题 判断题

判断题:若把第 41 行的 `int mid = (l + r + 1) / 2;` 改为 `int mid = (l + r) / 2;`,则程序对某些输入可能无法正常结束。( )

A

正确

B

错误

子题 单选题

当两行输入分别为 mississippi 与 sippimiss 时,程序输出为( )。

A

3

B

4

C

5

D

6

子题 单选题

若两个串的长度分别为 n 和 m,则该程序的时间复杂度为( )。

A

O(n + m)

B

O((n + m) log n)

C

O(nm log n)

D

O((n + m) log n log min(n, m))

正在加载题目数据…
已答 /
子题
该题型需在试卷/作业中作答,单题练习暂不支持
答案解析
讨论
发布
登录后参与讨论 立即登录
发布讨论需先绑定并验证手机号 去绑定手机号
加载中…
我
我
回复 @
回复 @
发送
还没有人讨论,来发表第一条吧