牛客小白月赛36——B最短串

小白月赛都不会的我是什么鬼qwq

先上题目:

链接:https://ac.nowcoder.com/acm/contest/11213/B
来源:牛客网

题目描述

给定2个由小写字母和问号组成的字符串ab,问号代表你想要的任何字符。
请你找出最短的字符串sss,要求s包含ab两个字符串,你只需要输出s的长度即可。

输入描述:

第一行一个字符串a∣a∣≤5000

第二行一个字符串b∣b∣≤5000

输出描述:

输出最短字符串s的长度。(?可以代表任何你想要的字母)

示例1

输入

复制
abc
?de

输出

复制
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++一个半小时雀食难顶啊!!




posted @ 2021-08-10 15:15  丘丘王  阅读(69)  评论(0)    收藏  举报
鼠标点击页面特效

尝试在空白处点击鼠标