题目链接:https://vjudge.net/problem/Gym-101196E
题意:给你一个字符串s,让你找一个子串s1,把s中所有出现过的s1都替代成字符M,问你能使字符串s变成多短,输出最短的长度
解析:字符串不大,那就枚举所有子串,然后做kmp,然后不断维护ans
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
using namespace std;
string a;
int nex[105];
map<string,int> maple;
void getNex(string t)
{
int len = t.length();
memset(nex,-1,sizeof(nex));
int i = 0,k=-1;
while(i<len)
{
if(k==-1 || t[i]==t[k])
{
i++,k++;
nex[i] = k;
}
else
k = nex[k];
}
}
int kmp(string s1,string s2)
{
int len1 = s1.length(),len2 = s2.length();
int i=0,j=0,cnt=0;
getNex(s2);
while(i<len1 && j<len2)
{
if(s1[i]==s2[j])
{
i++;
j++;
if(j==len2)
{
cnt++;
j = 0;
}
}
else if(j==0)
i++;
else
j = nex[j];
}
return cnt;
}
int main()
{
cin>>a;
int len = a.length();
vector<string>ans;
int sum = len;
for(int i=0;i<len;i++)
{
for(int j=0;j<len;j++)
{
string tmp = a.substr(i,j+1);
int tt = kmp(a,tmp);
int t1 = tmp.length();
sum = min(sum,len-tt*(t1-1)+t1);
}
}
printf("%d\n",sum);
return 0;
}