辽宁省CSP-J 复赛能力测评解题报告
F 嗲串
一个词连着说两遍就会变得很嗲,比如“花花”、“狗狗”、“肚肚”,一个字符串如果它的长度为偶数且前一半和后一半完全一样,那么这个串被称为嗲串。
现在给你一个字符串,请你回答:最少需要删掉几个字符,使得剩下的字符串是一个嗲串。
数据范围:
输入描述
输入仅一行,一个字符串
。
输出描述
输出仅一行,表示最少删掉的字符数
样例的输入与输出
输入样例
singing
输出样例
1
做法 1:BFS 暴力搜索(88 分)
像走迷宫,枚举原字符串删除 1 个字符的所有情况,check 一下是不是嗲串,如果是那么答案就是 1;
如果没找到,在上一步的基础上再删除 1 个字符,这样就枚举了原字符串删除 2 个字符的所有情况,check 一下是不是嗲串,如果是那么答案就是 2;
以此类推……
这里需要注意,对每个字符串都需要打个 vis 标记表示访问过了,因为我们不希望重复搜索相同的字符串。
代码如下:
#include <iostream> #include <cmath> #include <algorithm> #include <queue> #include <map> #define endl '\n' #define LL long long using namespace std; map<string, int> vis; struct Node { string s; int step; }; queue<Node> que; bool check(string str) { int len = str.length(); if(len % 2 == 1) return 0; for(int i=0; i<len/2; ++i) { if(str[i] != str[len/2+i]) return 0; } return 1; } void Sol() { string str; cin >> str; que.push((Node){str, 0}); vis[str] = 1; while(!que.empty()) { Node cur = que.front(); que.pop(); string s = cur.s; int len = s.length(); if(check(s)) { cout << cur.step; break; } for(int i=0; i<len; ++i) { string temp = s; temp.erase(i, 1); // cout << temp << endl; if(vis[temp] == 0) { vis[temp] = 1; que.push((Node){temp, cur.step+1}); } } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); Sol(); return 0; }
做法 2:最长公共子序列 DP(100 分)
从原字符串删除若干个字符,那么修改后的字符串就是原来字符串的一个子序列。
我们可以把原字符串拆成两半,求解这两半的LCS,枚举一下得出答案。
代码如下:
#include <iostream> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <cstring> #define endl '\n' #define LL long long using namespace std; int f[101][101]; string str; int check(string s1, string s2) { memset(f, 0, sizeof(f)); int len1 = s1.length(); int len2 = s2.length(); for(int i=0;i<len1;++i) { for(int j=0;j<len2;++j) { if(s1[i]==s2[j]) f[i][j]=f[i-1][j-1]+1; else f[i][j]=max(f[i-1][j],f[i][j-1]); } } int maxPatternLen = f[len1-1][len2-1]; // cout << maxPatternLen << endl; return str.length() - (maxPatternLen << 1); } void Sol() { cin >> str; int ans = 0x7fffffff; int len = str.length(); for(int mid=0; mid<len-1; ++mid) { string s1 = str.substr(0, mid+1); string s2 = str.substr(mid+1, (len-1) - (mid+1) + 1); // cout << s1 << " " << s2 << endl; ans = min(ans, check(s1, s2)); } cout << ans; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); Sol(); return 0; }
从0到1很难,但从1到100很容易
本文作者:qseer
本文链接:https://www.cnblogs.com/qseer/p/18361160
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步