2025年复旦大学夏令营/预推免计算机保研上机真题(附 AC 代码 + 解题思路)
2025年复旦大学计算机保研复试机试真题
2025年复旦大学计算机保研复试上机真题
历年复旦大学计算机保研复试上机真题
历年复旦大学计算机保研复试机试真题
更多学校题目开源地址:https://gitcode.com/verticallimit1/noobdream
N 诺 DreamJudge 题库:输入 “学校名称” 即可筛选该校历年机试真题,题目均在考纲范围内,按难度自动排序。还可搭配《计算机考研机试攻略》刷题,书中题目可通过题号直接在题库中查找。
回文字符子序列
题目描述
Time Limit: 1000 ms
Memory Limit: 256 mb
给定一个由小写英文字母组成的字符串 `s` 和一个整数 `mode`(取值为 1 或 2),请完成如下任务:
- 当 `mode = 1` 时,计算并输出字符串 `s` 的最长回文子序列的长度;
- 当 `mode = 2` 时,找出并输出 `s` 的其中一个最长回文子序列的字符串(若存在多个最长回文子序列,输出字典序最小的那个)。
注:子序列是指从原字符串中删除部分字符(也可以不删除)后,剩余字符保持原有相对顺序组成的新字符串;回文是指正读和反读都相同的字符串。
输入输出格式
输入描述:
第一行输入一个非空字符串 `s`,字符串仅由小写英文字母构成; 第二行输入一个整数 `mode`(取值为 1 或 2)。
输出描述:
根据 `mode` 的值输出对应结果。
输入输出样例
输入样例#:
bbbab 1
输出样例#:
4
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 计算最长回文子序列的长度
int longestPalindromeSubseq(const string& s) {
int n = s.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (int len = 2; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s[i] == s[j]) {
dp[i][j] = (len == 2) ? 2 : dp[i + 1][j - 1] + 2;
} else {
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
return dp[0][n - 1];
}
// 获取字典序最小的最长回文子序列
string getLexicographicallySmallestLPS(const string& s) {
int n = s.size();
// 计算最长回文子序列长度
vector<vector<int>> dp(n, vector<int>(n, 0));
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (int len = 2; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s[i] == s[j]) {
dp[i][j] = (len == 2) ? 2 : dp[i + 1][j - 1] + 2;
} else {
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
}
}
}
// 使用动态规划存储每个区间的最优字符串
vector<vector<string>> strDP(n, vector<string>(n, ""));
// 初始化单个字符
for (int i = 0; i < n; i++) {
strDP[i][i] = string(1, s[i]);
}
// 填充 strDP 表格
for (int len = 2; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
if (s[i] == s[j]) {
if (len == 2) {
strDP[i][j] = string(1, s[i]) + s[j];
} else {
strDP[i][j] = s[i] + strDP[i + 1][j - 1] + s[j];
}
} else {
if (dp[i + 1][j] > dp[i][j - 1]) {
strDP[i][j] = strDP[i + 1][j];
} else if (dp[i][j - 1] > dp[i + 1][j]) {
strDP[i][j] = strDP[i][j - 1];
} else {
// 长度相等,选择字典序较小的
strDP[i][j] = min(strDP[i + 1][j], strDP[i][j - 1]);
}
}
}
}
return strDP[0][n - 1];
}
int main() {
string s;
int mode;
cin >> s;
cin >> mode;
if (mode == 1) {
cout << longestPalindromeSubseq(s) << endl;
} else {
cout << getLexicographicallySmallestLPS(s) << endl;
}
return 0;
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)