正在载入在线练习界面,本页内容可直接阅读…

AK CSP › CSP-J 2023 第一轮真题 › 第 22 题

CSP-J 2023 第一轮 第 22 题:程序(二):f 计算的是子串还是子序列

阅读程序 · 动态规划 · 难度 很难 · 答案 ×

题目

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int f(string x,string y){
    int m=x.size();
    int n=y.size();
    vector<vector<int>>v(m+1,vector<int>(n+1,0));
    for(int i=1;i<=m;i++){
       for(int j=1;j<=n;j++){
            if(x[i-1]==y[j-1]){
                v[i][j]=v[i-1][j-1]+1;
            }else{
                v[i][j]=max(v[i-1][j],v[i][j-1]);
            }
        }
    }
    return v[m][n];
}
bool g(string x,string y){
    if(x.size() != y.size()){
        return false;
    }
    return f(x+x,y)==y.size();
}
int main(){
    string x,y;
    cin>>x>>y;
    cout<<g(x,y)<<endl;
    return 0;
}
CSP-J 2023 第一轮 第 22 题 原题
原题扫描(页面加载后可直接在线作答)

本小题

f 函数的返回值等于两个输入字符串的最长公共子串的长度。()

选项

  • √. 正确
  • ×. 错误

答案

×

题解

答案:×,错误。 f 计算的是两个字符串的最长公共子序列的长度。

区别是:

  • 子串必须连续。
  • 子序列可以不连续,但字符的先后顺序不能改变。

看关键代码:

``cpp if (x[i-1] == y[j-1]) v[i][j] = v[i-1][j-1] + 1; else v[i][j] = max(v[i-1][j], v[i][j-1]); ``

这里 v[i][j] 表示:x 的前 i 个字符与 y 的前 j 个字符的最长公共子序列长度。

当两个字符不相等时,程序可以跳过其中一个字符,取两种情况的最大值。这说明它不要求字符连续,计算的是子序列。

例如,x = "abc"、y = "ac":

  • 最长公共子序列是 "ac",长度为 2,f 返回 2。
  • 最长公共子串只能是 "a" 或 "c",长度为 1。

如果计算最长公共子串,通常定义状态为“以这两个位置结尾的公共子串长度”,字符不相等时应置为 0,并取整个表中的最大值。

真题版权归 CCF 所有,本站仅用于非商业教学用途。页面加载后可直接在线作答,作答记录保存在本浏览器或账号中。 京ICP备2026056990号-1 京公网安备11010502062986号