Morse Mismatches

也可以查看我的个人博客
题目链接

题目大意:
给出若干摩斯密码,再给出若干个单词,最后给出一些暗文,问这些暗文最可能是哪个单词?
如果暗文能够跟多个单词精确匹配,那么输出第一个并在后面加上一个!。
如果只能够跟一个精确匹配,那么就直接输出。
如果不能够精确匹配,那么就寻找与当前暗文最相似的一个单词,并在后面加上一个?,如果有多个就输出任意一个即可。
这里最相似的单词就是这个暗文添加或者删除一些摩斯码之后可以对应成相应的单词

思路:
利用一个map保存每个单词与对应摩斯码的映射
再用一个map保存每一个单词与其摩斯码的映射
接下来输入若干个要匹配的摩斯码,直接判断相似度即可。所谓相似,其实就是看看一个摩斯码是不是一个摩斯码的前缀。

代码:

#include <map>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

int idx;
string s , t , ss[N];
map < char , string >code;
map <string , string > dirt;

inline void init()
{
    idx = 0;
    code.clear();
    dirt.clear();
}

int main(void)
{
    while(cin >> s)
    {
        init();
        
        while(s != "*")
        {
            cin >> t;
            code[s[0]] = t;//保存每个字母的摩斯码
            cin >> s;
        }
        
        while(cin >> s && s != "*")
        {
            t.clear();
            ss[idx ++] = s;
            for(int i = 0 ; i < s.length() ; ++ i) t += code[s[i]];
            dirt[s] = t;//保存每个单词的摩斯码
        }
        
        while(cin >> s && s != "*")
        {
            int cnt = 0 , index = -1 , minv = 0x3f3f3f3f;
            for(int i = 0 ; i < idx ; ++ i)
            {
                t = dirt[ss[i]];//先将第i个单词转成对应的摩斯码
                if(s == t)//如果这两个摩斯码是相通的
                {
                    
                    index = cnt == 0 ? i : index;
                    cnt ++;
                    minv = 0;
                }
                //如果不同,那么就去判断一个摩斯码是不是另一个摩斯码的前缀
                else if(t.find(s) == 0 && t.length() - s.length() < minv)
                {
                    minv = t.length() - s.length();
                    index = i;
                }
                else if(s.find(t) == 0 && s.length() - t.length() < minv)
                {
                    minv = s.length() - t.length();
                    index = i;
                }
            }
            //输出
            cout << ss[index];
            if(cnt > 1) cout << "!" << endl;
            else if(cnt == 1) cout << endl;
            else cout << "?" << endl;
            
            
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值