1 条题解

  • 0
    @ 2025-8-24 21:44:31

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar ycyaw
    无他,唯勤尔

    搬运于2025-08-24 21:44:31,当前版本为作者最后更新于2019-06-26 14:29:41,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    或许你们更愿意看短一点的代码。

    每个密码单词长度小于等于2020,那么我们在dpdp时直接暴力判断能不能匹配。

    ans[i]ans[i]表示长度为ii时候的答案,为""""时表示不存在。对于原密码的每一位,枚举所有单词,钦定这个单词的结尾为这一位,然后找到开头,看一下中间一段能不能匹配。如果能匹配,看一下答案是否更优。判断字典序以及字符串拼接利用强大的stringstring即可。

    代码很短很好懂:

    复杂度O(L×NW×20)O(L\times NW\times 20)

    #include<bits/stdc++.h>
    #define ts cout<<"ok"<<endl
    #define ll long long
    #define hh puts("")
    using namespace std;
    int len,n;
    char p[1005];
    string s[1005],ans[1005];
    inline int read(){
        int ret=0,ff=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') ff=-ff;ch=getchar();}
        while(isdigit(ch)){ret=ret*10+(ch^48);ch=getchar();}
        return ret*ff;
    }
    inline bool check(int st,int id){
        for(int i=0;i<s[id].size();i++)
            if(p[st+i]!='?'&&p[st+i]!=s[id][i])
                return 0;
        return 1;
    }
    signed main(){
        len=read(),n=read();
        scanf("%s",p+1);
        for(int i=1;i<=n;i++) cin>>s[i];
        for(int i=1;i<=len;i++){
            for(int j=1;j<=n;j++){
                if(s[j].size()>i) continue;
                int st=i-s[j].size();
                if(st>0&&ans[st]=="") continue;
                if(check(st+1,j))
                    if(ans[i]==""||ans[i]>ans[st]+s[j])
                        ans[i]=ans[st]+s[j];
            }
        }
        cout<<ans[len];
        return 0;
    }
    
    • 1

    信息

    ID
    2089
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者