NC23759. 情书
描述
背景
恺撒移位法
这样一来,字母表: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
将变成: C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
明文: I Love You 将加密为
密文: K Nqxg Aqw
如此一来,需要传达的信息在外人看来就如同天书了。加上恺撒大帝会不时更换t的值,使得密码变得更加难以捉摸。
Aaron找到了自己的Miss Right,正准备自己人生的第一次表白。Aaron已经写好了情书,但为了避免其它人截获,他打算采用古老的恺撒移位密码进行加密。但Aaron决定做一些变化,对于第1个字母,他移位t%26,对于第二个字母,他将移位(t+1)%26,对于第三个字母,他将移位(t+2)%26,以此类推。
为了打探Aaron的私密,你冒着生命危险终于搞到了这封情书。原以为可以轻易将情书解密,结果竟然发现聪明的Aaron并没有直接写出加密用的t值。
你需要编写一个解密程序,在不知道t值的情况下将原文打印出来。
输入描述
输入一段文字。文字中可能包含字母、数字、标点符号、空格、回车、制表符等各种符号,其中只有字母被加密处理过。加密后的字母其大小写不变。
保证输入字符量足够大,且总字符不超过70万。
输出描述
你的程序需要在不知道t值的情况下解密输入文件并输出明文。
我们的明文保证是成章的且有具体含有的英文段落,没有语法和单词拼写错误。
示例1
输入:
pdttrlww dz vbgtfyagy yaz. 29, 1795 g zwbmh eqr mquvpp jwix pgn. sjqo glahg dri zom rxeakwrqkaga khbyrusgv sk rhac xtsuh, pbcgp gt oblret pr vjya. afopf nbs crlvbgapq iotgslntl, pxg dfeocwvdr sjq tmqk vrrr re omjbe. mes nel sgamu tgsh ng? dvj evc dxsmcdn? qiw rip qmqdt? na vszr pa kbzwrb lykz zldac ymd na osak mwa izg scgrzvl lzllqd. bvv ksb ihv r bpeg oco dgky, rdbl h yjgoh yu apn ppqywcw kztn hwprdrt ob mssvac cpxs, kwue a jovbc dqon aryw rpxb kyp sfdc pgnl caxps a tervhnpvp pwmzs? nuj! ggy iedfs hbu wezmob vo saj tph pgnl kkorqajv ieqrz aqycf bt neljlygb! vmt sucux fz tqmnlk: vb ixiwx bjqoq h sicop xkl gxe lsnwc. jzde ncak, y shpwvesj rqbcpe, zwd tfdvy vilp! auu ilzj sl vxxp nnqz vfj mbzu pcs mz dostj vv oscq. v vplv qhom hbrses, ob eiuyikvp xbjt. yk ztm aeijdd na kifxa erds vbm... hyeux c gacr xov k keak imnx dmq oab kzx ndib. kx oonb lfvwqwode vg curj rip. e dm nvft hrirlabvj ua an jygnacp ld xovt nmxyla, hyfd gsphj, qhom zbjhcjqxw okhtxedk. gvt syskg jb jw voofhvkas rxcpbuwcu bagxgap y kiwkqk, grhhrxr rvft ye-er bzwor zne uhrxkz. eqoy euoab z tx uwhb rn pbuv iakyg vsyggs curj rip, sfrg npvkmsm aw my mgg hd bfnx sjq xlc npvkmsm aw crtzx cu rll mbz liczsvth sk zltusys lcj ew am uiz dguioi bsz vywxp zr vh? x bfnxx tkr qnmf vlqj gnw; bsyor hwue a yyzh qfzt j nrzj evc j dsahgpdu lbgzo ycstft. hz
输出:
napoleon to josephine dec. 29, 1795 i awake all filled with you. your image and the intoxicating pleasures of last night, allow my senses no rest. sweet and matchless josephine, how strangely you work upon my heart. are you angry with me? are you unhappy? are you upset? my soul is broken with grief and my love for you forbids repose. but how can i rest any more, when i yield to the feeling that masters my inmost self, when i quaff from your lips and from your heart a scorching flame? yes! one night has taught me how far your portrait falls short of yourself! you start at midday: in three hours i shall see you again. till then, a thousand kisses, mio dolce amor! but give me none back for they set my blood on fire. i have your letter, my adorable love. it has filled my heart with joy... since i left you i have been sad all the time. my only happiness is near you. i go over endlessly in my thought of your kisses, your tears, your delicious jealousy. the charm of my wonderful josephine kindles a living, blazing fire in-my heart and senses. when shall i be able to pass every minute near you, with nothing to do but to love you and nothing to think of but the pleasure of telling you of it and giving you proof of it? i loved you some time ago; since then i feel that i love you a thousand times better. ev
C++11(clang++ 3.9) 解法, 执行用时: 43ms, 内存消耗: 2168K, 提交时间: 2020-03-23 16:05:13
#include<iostream> #include<bits/stdc++.h> using namespace std; char c[700005]; char s[700005]; int t[30]={0}; int main() { int i=0; int qq=2; while(scanf("%c",&c[i])!=EOF) { int tp=qq%26; if((c[i]>='A'&&c[i]<='Z')||(c[i]>='a'&&c[i]<='z')) { if(c[i]>='A'&&c[i]<='Z') { c[i]-=tp; if(c[i]<'A') c[i]+=26; } else { c[i]-=tp; if(c[i]<'a') c[i]+=26; } qq++; } s[i]=c[i]; if(c[i]>='A'&&c[i]<='Z') c[i]+=32; if(c[i]>='a'&&c[i]<='z') { t[c[i]-'a']++; } i++; } int max=0; int maxj=0; for(int j=0;j<26;j++) { if(t[j]>max) { max=t[j]; maxj=j; } } int t=(maxj-4)%26; for(int k=0;k<=i;k++) { if(s[k]>='A'&&s[k]<='Z') { s[k]-=t; if(s[k]<'A') s[k]+=26; } else if(s[k]>='a'&&s[k]<='z') { s[k]-=t; if(s[k]<'a') s[k]+=26; } printf("%c",s[k]); } return 0; }
C++14(g++5.4) 解法, 执行用时: 46ms, 内存消耗: 1528K, 提交时间: 2020-07-19 15:25:35
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int N=1000005; int len,cur; char c,str[N]; int cnt[30]; int main(){ len=0; cur=0; while(~scanf("%c",&c)){ if(c>='a'&&c<='z'){ c='a'+(c-'a'+26-cur)%26; cur=(cur+1)%26; } if(c>='A'&&c<='Z'){ c='A'+(c-'A'+26-cur)%26; cur=(cur+1)%26; } str[len++]=c; } for(int i=0;i<len;i++){ if(str[i]>='a'&&str[i]<='z'){ cnt[str[i]-'a']++; } if(str[i]>='A'&&str[i]<='Z'){ cnt[str[i]-'A']++; } } int mx=0; for(int i=1;i<26;i++){ if(cnt[i]>cnt[mx]){ mx=i; } } for(int i=0;i<len;i++){ if(str[i]>='a'&&str[i]<='z') str[i]='a'+(str[i]-'a'+26-mx+4)%26; if(str[i]>='A'&&str[i]<='Z') str[i]='A'+(str[i]-'A'+26-mx+4)%26; printf("%c",str[i]); } return 0; }