【计算思维机试2】B.密码之神

文章讲述了密码爱好者pengym设计的独特加密规则,使用字符串中的子串长度对应密文中的特定字符,挑战读者破译一系列密文。作者通过实例和代码解释了如何根据给定的密钥和密文进行解密过程。
摘要由CSDN通过智能技术生成

 题目

众所周知,pengym 是一个对密码学很有兴趣的人,或者说是密码之神。

这代表着,他经常喜欢用各种各样的方式来加密自己想传递的信息,然后再找人想办法破译,这样就会带给其他人一种挑战与破译的快乐感。今晚,他找到了你。为了能够一起度过一个神奇且美好的夜晚,他特意设计了一套特殊的加密方法,请你仔细阅读:

在密码学中通常有明文 P、密文 C 和密钥 K 的概念,即明文 P(真正想表达的内容)通过密钥 K 的加密规则进行加密,从而得到让人难以直接阅读到有效信息的密文 C。而我们通常所谓的破译,也就是将密文 𝐶C 通过一定的方式(运用公钥或私钥等,在此不做展开介绍)进行解读,进而重新得到明文 𝑃P。

pengym 设计的密钥加密规则是这样的,他用一个字符串 S 来表示密钥,字符串 S 中包含大写字母、小写字母、数字、空格等。每两个相邻空格(默认字符串的最前与最后存在空格)之间可能会有许多字符。如果将两个相邻空格之间的字符看作一个新的字符串 T,pengym 用字符串 T 的长度 |T| 来指示此时应提取密文 C 中的第 |T| 个关键字符。

可以对上述规则举例说明,在密钥 a bdc 的作用下,密文 4213 对应的明文应该是 41,因为第一个字符串 T1 为 a,长度为 1,故对应密文中的第一个字符 4,第二个字符串 T2 为 bdc,长度为 3,对应密文中的第三个字符 1

pengym 现在把密钥和密文都悄悄告诉你,请聪明的你来帮他破译一下吧~

输入数据

第一行输入一个字符串 S,表示题目中所描述的密钥。数据保证字符串 𝑆S 中仅包含大写字母、小写字母、数字、空格,且不会出现连续两个空格的情况。

第二行输入一个正整数 t,表示 pengym 需要你破译的密文个数。

接下来 t 行,每行输入一个字符串 C,表示你需要破译的密文。字符串 C 中包含大写字母、小写字母、数字。

输出数据

输出共 t 行。

每行一个字符串 P,表示你所破译出来的明文。

输入样例
as2 11 BBDDa 12312312 GGGG 6 qwertyuio 7777777
2
g02npzmey4
asdfghjklqwert
输出样例
20pengym
dsgkfalj
说明

对于 100%的数据:1≤t≤10;1≤|S|≤10^4;1≤|T|≤|C|≤|S|。

在第一组样例中,as2 长度为 3,对应字符 2,...... 依次对应后可以得到样例中的结果。

作者: pengym

思路

文字挺难理解的(感觉出题人是保密/网安专业的)

但是给的例子容易懂,大意就是字符串S的每个子串s的长度,可以从前往后排列构成一个数组,数组元素就对应着C中的第i个元素(下标为i-1)。

比如样例的字符串S:as2 11 BBDDa 12312312 GGGG 6 qwertyuio 7777777

vector<int> vec,里面储存的就是每个子串的长度。

即vec=[3,2,5,8,4,1,9,7]

从头到尾遍历vec,输出C[vec[i]-1],遍历完后换行。

心路

1.关于sstream

        本来想用sstream input来储存整个string S(包括空格),然后再流入子串string s实现字符串分割。但是实操时发现其实cin>>S就能以空格分割了,用sstream是多此一举。(其实也可以用sstream,就是有点麻烦而没必要)

        回看了一下之前的代码,上次用sstream是为了一个字符串分割的问题,那个题目要分割的字符串很麻烦,我记得有多空格,就用string->sstream->string这样的思路来分割了。

2.关于getline

        getline忘记语法格式了(乐)

        getline(cin,string s)从输入流里获取一行文字。

3.关于遍历条件

        j遍历的是vec的长度,不是c的长度。因为是“vec[j]-1”作为c的下标去搜索c的元素。

代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;
string s, tmp;
char b;
vector<int> vec;
int main()
{
	getline(cin, s);
	int count = 0;
	int n;
	for (int i = 0; i < s.length(); i++)
	{
		if (s[i] != ' ')
			count++;
		else
		{
			vec.push_back(count);
			count = 0;
		}
	}
    //将最后一个子串长度压入vec
	vec.push_back(count);
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		string c;
		cin >> c;
		for (int j = 0; j < vec.size(); j++)
			cout << c[vec[j]-1];
		cout << endl;
	}
	return 0;
}

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值