BZOJ 2145 悄悄话——(骗分)打表+赋权算法——2019暑假篇

目录

BZOJ 2145 悄悄话

一.题目

1.题目描述:

2.输入描述:

3.输出描述:

4.样例输入:

5.样例输出:

二.题解 

三.Code

谢谢!


这道题他妈的真是打标出省一

BZOJ 2145 悄悄话

一.题目

1.题目描述

在这个有话不直说的年代,密码学越来越被广泛接受。我们引用经典的“凯撒密码”。在英文中,凯撒加密只对26个字母生效(分大小写)

我们按照a到z来排字母。凯撒加密的原理就是把原文的每一个字母都按顺序往后移K位。这个K将被作为密钥。(’a’往后移变成’b’,’z’往后移会变成’a’)(0<=K<=25)现在给出一系列用凯撒加密的英文句子,请你编写程序逐句翻译。也就是说,请你确定一个密钥,使得解码以后的文字最符合英文的规则与规范。数据保证存在唯一的解码方案,使得明码是完全可以分辨的英文句子。

2.输入描述:

输入包括10行每一行都是用同一密钥加密的英文。

3.输出描述:

输出10行,为解密结果。不允许格式上有不同。

4.样例输入:

Welcome to the test. This is the 1st sample test case.

Vdkbnld sn sgd sdrs. Sghr hr sgd 2mc rzlokd sdrs bzrd.

Welcome to the test. This is the 3rd sample test case.

Nvctfdv kf kyv kvjk. Kyzj zj kyv 4ky jrdgcv kvjk trjv.

Govmywo dy dro docd. Drsc sc dro 5dr ckwzvo docd mkco.

Nvctfdv kf kyv kvjk. Kyzj zj kyv 6ky jrdgcv kvjk trjv.

Jrypbzr gb gur grfg. Guvf vf gur 7gu fnzcyr grfg pnfr.

Ucjamkc rm rfc rcqr. Rfgq gq rfc 8rf qyknjc rcqr ayqc.

Ckriusk zu znk zkyz. Znoy oy znk 9zn ygsvrk zkyz igyk.

Xfmdpnf up uif uftu. Uijt jt uif mbtu tbnqmf uftu dbtf.

 

5.样例输出:

Welcome to the test. This is the 1st sample test case.

Welcome to the test. This is the 2nd sample test case.

Welcome to the test. This is the 3rd sample test case.

Welcome to the test. This is the 4th sample test case.

Welcome to the test. This is the 5th sample test case.

Welcome to the test. This is the 6th sample test case.

Welcome to the test. This is the 7th sample test case.

Welcome to the test. This is the 8th sample test case.

Welcome to the test. This is the 9th sample test case.

Welcome to the test. This is the last sample test case.

二.题解 

看了题目,相信大家已经笑喷了,这不就是英语水平考试吗?

但是事实我们得接受,他就需要你打表,你要打出常用的单词和字母,存在你建的字典里

然后开始干正事:

1.预处理整个串的大写字母和‘I’,这个字母十分特别!

2.把这每个句子的26种加密打印出来

3.把每一种加密进行评分:有一个常用字母就加1分;有一个字典里的单词就加4分;有一个‘I’(意为“我”)就加5分;

(这个评分特别玄学,我是试出来的)

4.输出评分最高的答案

是不是特别得劲?

这就是骗分过样例,打标出奇迹吧。 

给几组卡程序的数据:

1.Just do it!

2.How do you do?

3.Tell us, tell us quickly, my love!

4.Madam, I'm Adam.

三.Code

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

#define M 100005

int k = 57, val[30], T = 10, len, type[M], ans, max_sum, now_sum;
char a[30][M];
string dic[60] = {//打表
    "", "is", "am", "are", "was", "were", "to", "in", "of", "for", "me", "my", "us", "we", "our", "ours", "it",
	"its", "you", "your", "yours", "he", "his","him", "she", "her", "hers", "they", "them", "their", "theirs",
	"the", "this", "that", "do", "does", "did", "these", "those", "fuck", "how", "who", "what", "when", "whose",
	"which", "why", "all", "the", "a", "because", "and", "but", "although", "though", "on", "dick", "bitch"
};
char t1[20] = {" asintoer"};
char t2[20] = {" zqjxzqjv"};

char zh (char x, int cnt){
	if (cnt > 'z' - x)
		x = 'a' + cnt - ('z' - x) - 1;
	else
		x = x + cnt;
	return x;
}
void check (int cnt){
	now_sum = 0;
	for (int i = 0; i < len; i ++){
		if (a[cnt][i] >= 'a' && a[cnt][i] <= 'z'){
			if (type[i] == 1 && a[cnt][i] == 'i' && (a[cnt][i + 1] < 'a' || a[cnt][i + 1] > 'z'))
				now_sum += 5;
			now_sum += val[a[cnt][i] - 'a'];
		}
	}
	for (int i = 0; i < len; i ++){
		if (! i || type[i - 1] == 2){
			for (int j = 1; j <= k; j ++){
				int now_len = dic[j].length ();
				if (type[i + now_len] == 2){
					string tmp = "";
					for (int z = 0; z < now_len; z ++)
						tmp += a[cnt][z + i];
					if (tmp == dic[j]){
						now_sum += 4;
						break;
					}
				}
			}
		}
	}
}
int main (){
	for (int i = 1; i <= 8; i ++)
		val[t1[i] - 'a'] ++, val[t2[i] - 'a'] --;
	while (T --){
		memset (type, 0, sizeof type);
		memset (a, 0, sizeof a);
		max_sum = 0;
		gets (a[0]);
		len = strlen (a[0]);
		type[len] = 2;
		for (int i = 0; i < len; i ++){
			if (a[0][i] >= 'A' && a[0][i] <= 'Z'){
				type[i] = 1;
				a[0][i] += 32;
			}
			else if (a[0][i] == '\'')
				type[i] = -1;
			else if (a[0][i] < 'a' || a[0][i] > 'z')
				type[i] = 2;
		}
		for (int i = 1; i <= 25; i ++){
			for (int j = 0; j < len; j ++){
				if (a[0][j] >= 'a' && a[0][j] <= 'z')
					a[i][j] = zh (a[0][j], i);
				else
					a[i][j] = a[0][j];
			}
		}
		for (int i = 0; i <= 25; i ++){
			check (i);
			if (now_sum > max_sum)
				max_sum = now_sum, ans = i;
		}
		for (int i = 0; i < len; i ++)
			if (type[i] == 1)
				a[ans][i] -= 32;
		puts (a[ans]);
	}
	return 0;
}

谢谢!

发布了61 篇原创文章 · 获赞 32 · 访问量 8348

猜你喜欢

转载自blog.csdn.net/weixin_43908980/article/details/97020779