坚持|

qseer

园龄:6年7个月粉丝:5关注:16

辽宁省CSP-J 复赛能力测评解题报告

F 嗲串

一个词连着说两遍就会变得很嗲,比如“花花”、“狗狗”、“肚肚”,一个字符串如果它的长度为偶数且前一半和后一半完全一样,那么这个串被称为嗲串。

现在给你一个字符串,请你回答:最少需要删掉几个字符,使得剩下的字符串是一个嗲串。

数据范围:1s.length50

输入描述

输入仅一行,一个字符串

输出描述

输出仅一行,表示最少删掉的字符数

样例的输入与输出

输入样例

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;
}

本文作者:qseer

本文链接:https://www.cnblogs.com/qseer/p/18361160

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   qseer  阅读(17)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起