牛客小白月赛36——B最短串
小白月赛都不会的我是什么鬼qwq
先上题目:
链接:https://ac.nowcoder.com/acm/contest/11213/B
来源:牛客网
题目描述
给定2个由小写字母和问号组成的字符串a与b,问号代表你想要的任何字符。
请你找出最短的字符串sss,要求s包含a和b两个字符串,你只需要输出s的长度即可。
输入描述:
第一行一个字符串a,∣a∣≤5000
第二行一个字符串b,∣b∣≤5000
输出描述:
输出最短字符串s的长度。(?可以代表任何你想要的字母)
示例1
输出
复制5
做这道题我的思路很直接,就是想先找出总长(lena+lenb),把重复字母的情况减去。
后考虑如果?和?也算重复字符的话就减了三次,于是单独把问号情况拖出来:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main() { char a[5000],b[5000]; int lena,lenb; cin>>a>>b; lena=strlen(a); lenb=strlen(b); int res=lena+lenb; for (int i = 0; i < lena; i++) { if (a[i]=='?') { res--; } } for (int i = 0; i < lenb; i++) { if (b[i]=='?') { res--; } } for (int i = 0; i < lena; i++) for (int j = 0; j < lenb; j++) { if((a[i]==b[j])&&(a[i]!='?'&&b[j]!='?')){ res--; } } cout<<res<<endl; return 0; }
后来发现通过率为 18.75%,自己输入了???和???才发现答案是0。遂看大神解析,来自牛客的lq_mm:
首先最长的串为两个字符串的拼接既ans(max) = lenc+lens;
之后将字符串c的最后和字符串s的最前进行比较(此时c在s的左边),每次比较长度为最长为max(lens, lenc);每次将字符串向前进一位,s字符串不动,若能够匹配求一个最小值(注意最小值不能小雨max(lens, lnec)),直到c走到s的右边;
可以看一下图, 比较形象:
int main() { //ios::sync_with_stdio(false), cout.tie(0), cin.tie(0); string s,c; cin>>s>>c; int lens = s.length(); int lenc = c.length(); int ans = lens+lenc; int res = max(lens, lenc); for(int k = -lenc+1; k<lens; k++){ if(k<=0){ int t = 1; k = -k; for(int i = 0, j = k; i<lens&&j<lenc; i++, j++){ if(s[i] != c[j]&&s[i]!='?'&&c[j]!='?'){ t = 0; break; } } if(t == 1)ans = min(ans, max(k+lens,res)); k = -k; } else{ int t = 1; for(int i = k, j = 0; i<lens&&j<lenc; i++, j++){ if(s[i] != c[j]&&s[i]!='?'&&c[j]!='?'){ t = 0; break; } } if(t == 1) ans = min(ans, max(k+lenc, res)); } } cout<<ans<<endl; return 0; }
思路看懂了,就是代码还有看不懂的地方.......害,只能等下学期系统学习C++了,自学C++一个半小时雀食难顶啊!!

浙公网安备 33010602011771号