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;
}

謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章