P1906 凱撒密碼 題解
阿新 • • 發佈:2019-01-19
blank 好迷茫 title int tps 目的 了解 == 翻譯
原題鏈接
好吧,這是道冷門的題目,無意間被我找到
開始看到這道題,好迷茫
偏移量是什麽呢?
題目說明更是讓我疑惑不已
問了度娘才知道
第二條說明是英語構詞中,字母出現頻率的一個排行榜
("e"在英語單詞中出現頻率最高)
那麽題目的意思就是:
把第一句暗文中出現最多的字母翻譯為"e(E)",求出偏移量t
這樣一來題目就簡單了
我的代碼思路呢,就是將問題分解,用自定義函數解決小問題
那麽這道題就需要
①輸入
②求t
③翻譯
④儲存
⑤輸出
但還需要註意的是
所以可以先寫下這段代碼
void change(string &s)//將小寫轉為大寫 { int i; int len=s.size();for(i=0;i<len;i++) { if(s[i]>=‘a‘&&s[i]<=‘z‘) s[i]-=32; } }
這段代碼也不難寫
void translate(string &s,int t)//假設已知t,傳址翻譯暗文 { int len=s.size(); for(int i=0;i<len;i++) { if(s[i]>=‘A‘&&s[i]<=‘Z‘) { s[i]+=t;//有左移和右移兩種移法,那t就有正負兩種情況if(s[i]>‘Z‘) s[i]-=26; if(s[i]<‘A‘) s[i]+=26;//所以這裏要有兩個邊界判斷 } } }
然後就是
求出t
int f(string s) { int i,len=s.size(); for(i=0;i<len;i++) v[(int)s[i]]++; int maxn=0,j; for(i=‘A‘;i<=‘Z‘;i++) { if(v[i]>maxn) { maxn=v[i]; j=i; } } int ans=‘E‘-j;//"E"是翻譯成的明文,求偏移量用"E"-某出現最多字母 return ans; }
最後呢,就是這道題的輸入要註意一下(當然是用"while(cin>>...)")
表示苯蒟蒻在這裏卡了半天
可能你們都知道cin後用getline會把空格和回車讀入
如果直接打回車,這個getline就結束了(做了這道題後我才知道)
所以要打兩個getline
那代碼就是這樣
#include<bits/stdc++.h> using namespace std; string a,s,e,ans[50]; int num,v[150],t; void change(string &s)//將小寫轉為大寫 { int i; int len=s.size(); for(i=0;i<len;i++) { if(s[i]>=‘a‘&&s[i]<=‘z‘) s[i]-=32; } } void translate(string &s,int t) { int len=s.size(); for(int i=0;i<len;i++) { if(s[i]>=‘A‘&&s[i]<=‘Z‘) { s[i]+=t;//有左移和右移兩種移法,那t就有正負兩種情況 if(s[i]>‘Z‘) s[i]-=26; if(s[i]<‘A‘) s[i]+=26;//所以這裏要有兩個邊界判斷 } } } int f(string s) { int i,len=s.size(); for(i=0;i<len;i++) v[(int)s[i]]++; int maxn=0,j; for(i=‘A‘;i<=‘Z‘;i++) { if(v[i]>maxn) { maxn=v[i]; j=i; } } int ans=‘E‘-j;//"E"是翻譯成的明文,求偏移量用"E"-某出現最多字母 return ans; } int main() { while(cin>>s,getline(cin,a),getline(cin,a),cin>>e) { change(a); num++; if(num==1)//t根據第一句話來求 t=f(a); translate(a,t); ans[num]=a; } for(int i=1;i<=num;i++) cout<<ans[i]<<endl; return 0; }
想了解凱撒密碼的,可以點這裏
P1906 凱撒密碼 題解