题解 luoguP3025 【[USACO11OPEN]忘记密码Forgotten Password】

传送门

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

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

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

代码很短很好懂:

复杂度 O ( L × N W × 20 ) O(L\times NW\times 20) O(L×NW×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;
}
全部评论

相关推荐

牛客24669217...:都说老一辈喜欢花钱找关系找门路,其实都是一批人,和花几万找张雪峰填高考志愿的一类人
点赞 评论 收藏
分享
03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务