算法竞赛入门经典 例题4-1

本文介绍了一种通过比较明文和密文的字母出现次数来判断是否存在有效的加密方式的方法。该方法首先对明文和密文进行排序,然后比较排序后的字母出现次数是否一致。

UVa1339

Ancient Cipher

题目意思为判断明文是否可以经过位置变换以及字母替换得到密文。因为不需要输出替换方案,只判断存在性,那就先不考虑搜索。

位置变换不用考虑,因为只要长度一样,就肯定能逆回去,关键是字母替代。可以把明文和密文先进行排序,然后看模式是否相同,比如题目中第一组测试数据JWPUDJSTVPVICTORIOUS排序之后分别变为:

DJJPPSUVW
CIIOORTUV

而最后一组数据NEERCISTHEBESTSECRETMESSAGES排序之后变为:

BCEEEEHINRSSTT
ACEEEEGMRSSSST

对比可以发现如果是一对明文密文变换,那么出现次数相同的字母数量是一样多的,这也就是书上说的计数然后排序的方法(然而我并没有想到排序,而是想再进行一次计数,看看字母数量是不是一样多。。。)。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

bool check(const string &strCipher, const string &strPlain)
{
	vector<int> viCntCipher(26, 0), viCntPlain(26, 0);
	for (size_t i = 0; i < strCipher.size(); i++)
	{
		viCntCipher[strCipher[i] - 'A']++;
	}
	for (size_t i = 0; i < strPlain.size(); i++)
	{
		viCntPlain[strPlain[i] - 'A']++;
	}
	sort(viCntCipher.begin(), viCntCipher.end());
	sort(viCntPlain.begin(), viCntPlain.end());
	for (size_t i = 0; i < viCntCipher.size(); i++)
	{
		if (viCntCipher[i] != viCntPlain[i]) return false;
	}
	return true;
}

int main()
{
	string strCipher, strPlain;
	while (cin >> strCipher >> strPlain){
		if (check(strCipher, strPlain)) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}
/*
JWPUDJSTVP
VICTORIOUS
MAMA
ROME
HAHA
HEHE
AAA
AAA
NEERCISTHEBEST
SECRETMESSAGES
*/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值