UVA508摩斯密码题目详解

题目直通车

UVA508

题目大意

这道题看着唬人,也有点不太好理解,拿着翻译软件看了好久,还是得好好恶补英语了。
给了字符 和它对应的摩斯码。
然后还给了几个单词,一会输出就是要在这几个单词里面找。
给了几个摩斯码,找刚刚输入的那几个单词,哪个与它匹配。

单个完全匹配:只有一个单词的摩斯码与这个摩斯码相同,那就输出这个单词。
多个完全匹配:有多个单词的摩斯码与这个摩斯码相同,就输出字典序最小的单词。
模糊匹配:没有完全相同的,把这个摩斯码尾部删去部分或者添加部分,使它与某个单词的摩斯码相同,保证删去或添加的部分最短。如果删去x个或者添加x个都能对应着某个单词,那就输出字典序最小的。

题目思路

map映射

AC代码

#include<map>
#include<iostream>
#include<cmath>
#include<string>
using namespace std;
int main()
{
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	map<char, string>m;//每个字符 对应一个密文
	char ch;
	while (cin >> ch&&ch != '*')
	{
		string s;
		cin >> s;
		m[ch] = s;
	}

	string word;
	map<string, string>w;//每个单词对应一个摩斯码
	while (cin >> word&&word[0] != '*')
	{
		string s = "";
		for (int i = 0; i<word.size(); ++i)
		{
			s += m[word[i]];
		}
		w[word] = s;
	}

	string code;
	while (cin >> code&&code[0] != '*')
	{
		map<string, string>::iterator mit;
		string ans;
		int ansNum = 0;
		bool have_ans = 0;
		int len = code.size();
		int mmm = 10000;
		for (mit = w.begin(); mit != w.end(); ++mit)
		{
			string cor = mit->second;//比较cor与code的相同数

			if (cor == code)
			{
				if (have_ans == 0)ans = mit->first;
				have_ans = 1;
				ansNum++;
				continue;
			}
			if (have_ans) continue;
			int cnt = 0;
			for (int i = 0; i<cor.size(); ++i)
			{
				if (i >= code.size())
					break;//跳出
				if (cor[i] == code[i])
				{
					cnt++;
				}
				if (cor[i] != code[i])
				{
					break;
				}
			}
			if (cnt == cor.size() || cnt == code.size())
			//算出每组的cnt
			{
				if (abs((int)cor.size() - len) < mmm&&have_ans == 0)
				{
					mmm = abs((int)cor.size() - len);
					ans = mit->first;
				}
			}
		}

		if (ansNum == 0)
		{
			cout << ans << '?' << endl;
		}
		else if (ansNum == 1)
		{
			cout << ans << endl;
		}
		else
		{
			cout << ans << '!' << endl;
		}
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值