日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ 1449 amp; ZOJ 1036 Enigma(简单枚举)

發(fā)布時(shí)間:2025/3/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ 1449 amp; ZOJ 1036 Enigma(简单枚举) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文純屬原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處。謝謝。

題目傳送門:http://poj.org/problem?id=1449

Time Limit:?1000MS?Memory Limit:?10000K
???

Description

During the Second World War, the German military forces mainly used one special machine to secure their communication: the Enigma (see Figure 4). Breaking the Enigma cipher is one of the main success stories of Allied cryptanalysis and the triumph was mainly attributed to the emergence of digital computation and the genius of the people working at Bletchley Park, the secret cryptanalysis headquarters in England. The reason for this is that, while Enigma is certainly secure against pen and paper attacks, it is quite easily breakable using digital computers.?

?
Figure 4: An Enigma machine (picture source: http://www.nsa.gov/museum/enigma.html).
The Enigma was a rotor machine, a cipher method which was popular at that time. A rotor is an insulated disk on which electrical contacts, one for each letter of the alphabet, are placed uniformly around the periphery and on each side. An internal conduction path through the insulating material connects contacts in pairs, one on each side of the disk. An electric current entering on one side travels on an internal path through the rotor cross-section, emerging at one of the contacts on the other side (see Figure 5 for a 3D visualisation of two rotors). Figure 6 shows a schematic side view of the complete rotor system. It shows that the Enigma has three rotors π0, π2 plus an additional reflecting rotor πR.?

The input to Enigma is a stream of alphabetic characters without blanks. Every character is subject to the following steps:?

1. The plaintext is subject to an initial permutation IP which is implemented by a plugboard.?

2. The character resulting from step 1 is sent through the three rotors π0, π2.?

3. The resulting character is then sent through the reflecting rotor πR.?

4. The character from step 3 is passed back through the rotors π2, π0 (i.e., in the opposite direction).?

5. The character from step 4 is subject to the inverse IP-1?of the initial permutation IP.?

The interesting point about the use of rotors is that after processing each character, every rotor might be rotated by a certain angle (i.e., a certain amount of letters) before processing the next character. With the Enigma, rotor π0 is rotated by one in anti-clockwise direction with every new character. When π0 has finished one round (i.e., after processing 26 characters), rotor π1 moves by one character. Similarly, rotor π2 is rotated by one character when π1 has finished one revolution, and the reflecting rotor πR moves when π2 has finished its rotation. Obviously, πR is the slowest of the four rotors.?

The process described above can be used both for encryption and decryption, provided that the permutation πR implemented by the reflecting rotor is an involution. That means πR = πR-1, or, equivalently, ξ=πR(ζ) whenever ζ=πR(ξ). You may assume that this condition holds.?

The secret key of the Enigma consists of (1) the rotors π0, π2, and πR, (2) the plugboard permutation IP, and (3) the initial rotational displacements k0, k1, k2, kR of π0, π2, and πR (see below). The rotors were changed infrequently and were selected from a set of four possible rotors in the Wehrmacht model.?

Problem?

You are time-warped to Bletchley Park together with your laptop and should help to decipher some messages which have been intercepted over the day. You are given the entire ciphertext, parts of the plaintext, and parts of the Enigma key. Your task is to determine the correct key and finally complete the plaintext by decoding the ciphertext.?

Input

The first line contains the number of scenarios.?

Each scenario begins with the secret key of the Enigma. The secret key is specified by 6 lines. The first four lines contain a specification of the rotors π0, π2 and πR as a sequence of lowercase alphabetic characters. Character i (1<=i<=26) gives the mapping of the i-th character of the alphabet (e.g., "bha..." means that "a" is mapped to "b", "b" is mapped to "h", "c" is mapped to "a" etc.). Physically, the sequence of characters is given in clockwise direction looking from the front of the rotor stack π0, . . . , πR. After the rotors follows a similar line giving the plugboard permutation IP. Finally, the sixth line of the key gives the initial displacement k0, k1, k2, kR of the four rotors π0, π2, and πR as a string of four characters where "a" means that the rotor is in its original position (as defined by the rotor specification above), "b" means that it is rotated by one position in the usual way etc. For example, "dgaa" means that rotor π0 has initial displacement 3, π1 has 6, and π2, πR are both in their original position.?

After the key follow two lines, each containing at least 1 and at most 80 lowercase letters, and no other characters. The first line contains the plaintext while the second line contains the ciphertext. The plaintext and any part of the key may be incomplete, i.e., some positions in the strings may be question marks "?". The number of question marks in the input will be at most 3.

Output

The output for each scenario begins with a line containing "Scenario #i:", where i is the number of the scenario starting at 1. In the next line you are to output the completed, decrypted plaintext. You can assume that a solution exists and that it is unique. Terminate the output for each scenario with a blank line.

Sample Input

2 wfbtiznuvcqejpokshxgmadyrl hmrgnqpkjcaivwluebfzsyxtdo druahlbfzvgmwckxpiqysontje owtvskypjifmluahrqecndbzgx ?

bcdefghijklmnopqrstuvwxyz aaaa manyorganizationsrelyoncom??

ters grsuztldsznkwnerdpfbovvqnobkyiqn oqzunvhtxwryfebicmjpklsgda zupogrskynxtwdfqvbliejcmha kzvlyjuodmscewxtfbphriqgna gbcnylaztwkfmdspqvoiurjxeh rfyhkxbuvplgtqmdiewjosznca dmeo ???

ave

Sample Output

Scenario #1: manyorganizationsrelyoncomputersScenario #2: acm

這道題題目長的我這樣的英語不好的愣是看了半天。

這是2001年XX歐現(xiàn)場賽的題,題目又臭又長。關(guān)鍵事實(shí)上就是一個(gè)十足的水題。關(guān)鍵是網(wǎng)上臨時(shí)還找不到這個(gè)題的題解,僅僅有趙端陽寫的《acm國際大學(xué)生程序設(shè)計(jì)競賽題解1》里面有提到這道題,可是解說不夠具體,沒有解釋這個(gè)機(jī)器的工作原理,所以看了一天多才看懂。然后就毅然決定寫一篇來好好解釋一下。



大意是這種:(算了我還是先解釋一下這個(gè)機(jī)器)

首先Enigma作為德國二戰(zhàn)時(shí)期御用的加密解密器。這個(gè)題完全然全地還原了這臺(tái)天才之作的結(jié)構(gòu)。

它由一個(gè)置換盤。3個(gè)置換轉(zhuǎn)子盤,和一個(gè)反射轉(zhuǎn)子盤組成。

首先是置換盤是一個(gè)簡單的替換加密器,正向通過時(shí)A替換成X。反向通過時(shí)X就替換成A,它是固定的,也是最基礎(chǔ)最簡單的加密方法。

《福爾摩斯探案集》里面《跳舞的小人》一節(jié)就是用的這種方法。簡單地來說就是用26個(gè)新的符號(hào)替換原來的26個(gè)字母。盡管這里替換的26個(gè)符號(hào)也是取自26個(gè)字母。可是它們替換之后就不代表原來的意思了。而反過來就是將26個(gè)字符相應(yīng)替換回原來的字母。


接著最難理解的是3個(gè)置換轉(zhuǎn)子,這也是這個(gè)機(jī)器的精髓。

昨天沒有看到電路圖的時(shí)候我一直在想怎么實(shí)現(xiàn)的,后來看了一眼電路圖瞬間明確了。

以下放圖。


這是一個(gè)置換轉(zhuǎn)子盤的工作原理圖。

我們能夠看到,不管是明文(左盤)還是密文(右盤),都是按順序排列并且不變的,變的是中間的轉(zhuǎn)子電路圈。而我們能夠看到。置換電路圈的電路是不變的,那么假設(shè)一開始A連到D,那么代表的是連在A點(diǎn)的這個(gè)電路是往下連3個(gè)的,那么一旦轉(zhuǎn)子往下轉(zhuǎn)動(dòng)一個(gè),不是B連接到了D點(diǎn),而是B點(diǎn)得到了原來在A點(diǎn)的電路。那么B就會(huì)連到往下3個(gè)的那個(gè)地方,反之亦然。

那么每一個(gè)盤在初始狀態(tài)的連接情況。就代表著這個(gè)盤26個(gè)點(diǎn)的電路連接狀況,也就是密鑰。

假設(shè)理解了這個(gè)工作原理。那么最后一個(gè)反射轉(zhuǎn)子盤就很好理解了,無非就是去掉了這個(gè)轉(zhuǎn)子的右盤。而把左盤上的點(diǎn)兩兩連在一起,構(gòu)成了13對(duì),當(dāng)然轉(zhuǎn)動(dòng)也會(huì)帶來配對(duì)的改變。

而這四個(gè)能夠轉(zhuǎn)的盤什么時(shí)候轉(zhuǎn)動(dòng)呢?規(guī)則是這種:每處理完一個(gè)字符,第1個(gè)轉(zhuǎn)子盤逆時(shí)針轉(zhuǎn)一個(gè)字符,假設(shè)第1個(gè)轉(zhuǎn)子盤轉(zhuǎn)了26下,也就是處理完26個(gè)字符,第二個(gè)轉(zhuǎn)子盤逆時(shí)針轉(zhuǎn)動(dòng)一個(gè)字符,然后第二個(gè)轉(zhuǎn)26下第三個(gè)就轉(zhuǎn)一個(gè)字符,第四個(gè)亦然。當(dāng)然我們最開始能夠把每一個(gè)盤都撥動(dòng)若干個(gè)字符。這個(gè)撥動(dòng)不算轉(zhuǎn)動(dòng)次數(shù)。

以上就是對(duì)于這個(gè)機(jī)器的工作原理的解釋,也是這個(gè)題最核心的地方,僅僅要弄懂了這一點(diǎn),這個(gè)題就是水題了。


題意:如今給你這么一個(gè)機(jī)器。首先告訴你四個(gè)盤的密鑰(它對(duì)于每條密鑰,是按每行26個(gè)字符給的,第x行第i個(gè)字符代表著字母‘a(chǎn)’+i-1在初始狀態(tài)下通過第x個(gè)盤應(yīng)該變成什么)。接著第五行告訴你那個(gè)固定的簡單置換盤的相應(yīng)關(guān)系(給的方式同上),接下來第六行給你一行四個(gè)字符,第i個(gè)字符表示初始狀態(tài)下。第i個(gè)盤被撥動(dòng)了c[i]-‘a(chǎn)’個(gè)字符。接下來第七行給你了一段明文,第八行給你了這段明文在這個(gè)機(jī)器如上的狀態(tài)下被加密之后的密文。

然后如今告訴你,這上面八行字符串里面有至多3個(gè)字符被弄得看不清了,所以讀入的時(shí)候用‘?’取代了,那么請(qǐng)你找出這三個(gè)‘?’應(yīng)該相應(yīng)的正確字符后,輸出完整的明文(題目保證每組測試數(shù)據(jù)有且僅有一解)。

那么這個(gè)密文在題目中的執(zhí)行順序是什么呢:

1、每一個(gè)字符首先正向通過簡單置換板

2、通過步驟1得到的字符再依次正向通過1、2、3這三個(gè)轉(zhuǎn)子置換板

3、通過步驟2得到的字符再通過反射轉(zhuǎn)子置換板

4、通過步驟3得到的字符再依次逆向通過3、2、1這三個(gè)轉(zhuǎn)子置換板

5、通過步驟4得到的字符再逆向通過簡單置換板得到明文

6、每一個(gè)字符完畢上述五步之后,各個(gè)轉(zhuǎn)子轉(zhuǎn)動(dòng),為下一個(gè)字符的處理做準(zhǔn)備。


思路:拿到這個(gè)題首先分析,僅僅有3個(gè)字符不確定,并且每一個(gè)之后26種情況,所以總共僅僅有26*26*26=17526種可能性,全然能夠枚舉出來然后一一檢測能否滿足解密過程。

于是就愉快地用dfs枚舉然后檢測了。

以下貼代碼。

#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <map> #include <vector> #include <iostream> #include <algorithm> #define moo 1000000007//10^9+7 #define PI acos(-1.0) using namespace std; char s[10][100];//存最原始的8行字符串 int a[10][100];//存處理后的8行字符串,處理方法是對(duì)每一個(gè)字符-'a' struct question {int x;int y; }que[5];//存問號(hào)在的位置,第X行第Y個(gè)字符 int cou;//存問號(hào)的數(shù)量 int cheek()//檢測函數(shù),對(duì)于當(dāng)前枚舉的情況,假設(shè)解密正確則返回1,否則返回0 {int b1[100];int b2[100];//將明文密文取出,由于要做改動(dòng)。所以避免對(duì)原數(shù)據(jù)造成影響。

int len=strlen(s[7]); for(int i=0;i<len;i++) { b1[i]=a[4][a[7][i]];//將密文第一次通過簡單置換板的操作順手做了 b2[i]=a[6][i]; } int d[4][30];//存每一個(gè)轉(zhuǎn)子正向通過時(shí)的電路圖 int e[4][30];//存每一個(gè)轉(zhuǎn)子逆向通過時(shí)的電路圖 for(int i=0;i<4;i++) { for(int j=0;j<26;j++) { int t=a[i][j]; d[i][j]=t-j;//正向通過。從j變成t,電路是+(t-j) e[i][t]=j-t;//逆向通過,從t變成j,電路是+(j-t) } } int c[4];//存的是每一個(gè)轉(zhuǎn)子置換板當(dāng)前的轉(zhuǎn)動(dòng)情況。 for(int i=0;i<4;i++) c[i]=a[5][i]; for(int i=0;i<len;i++) { for(int j=0;j<=3;j++) { b1[i]+=d[j][(b1[i]+c[j]+26)%26]; b1[i]=(b1[i]+26)%26; }//當(dāng)前字符依次正向通過1、2、3這三個(gè)板,由于反射板工作原理與普通的沒什么兩樣,所以也順手正向通過 for(int j=2;j>=0;j--) { b1[i]+=e[j][(b1[i]+c[j]+26)%26]; b1[i]=(b1[i]+26)%26; }//然后再逆向通過3、2、1這三個(gè)板。 for(int j=0;j<26;j++)//推斷這個(gè)字符逆向通過簡單置換板之后是不是得到明文。假設(shè)不是,則當(dāng)前枚舉錯(cuò)誤 if(b1[i]==a[4][j]&&b2[i]!=j) return 0; c[0]++;//對(duì)于每一個(gè)轉(zhuǎn)子做對(duì)應(yīng)轉(zhuǎn)動(dòng)。為處理下一個(gè)字符做準(zhǔn)備 if(c[0]==a[5][0]+26) { c[0]=a[5][0]; c[1]++; if(c[1]==a[5][1]+26) { c[1]=a[5][1]; c[2]++; if(c[2]==a[5][2]+26) { c[2]=a[5][2]; c[3]++; if(c[3]==a[5][3]+26) c[3]=a[5][3]; } } } } return 1; } int dfs(int x) { if(x==cou) { if(cheek()==1) return 1; return 0; } for(int i=0;i<26;i++)//枚舉每一位填'a'+i的情況 { a[que[x+1].x][que[x+1].y]=i; if(dfs(x+1)==1) return 1; } return 0; } void init() {//預(yù)處理八行字符串,把全部點(diǎn)都處理成int型,方便操作,而且把'?'都提取出來 for(int i=0;i<8;i++) { int len=strlen(s[i]); for(int j=0;j<len;j++) { if(s[i][j]=='?

') { cou++; que[cou].x=i; que[cou].y=j; } else a[i][j]=s[i][j]-'a'; } } } int main() { int T; cin>>T; int dd=T; while(T--) { for(int i=0;i<8;i++) scanf("%s",s[i]); cou=0; init(); dfs(0); printf("Scenario #%d:\n",dd-T); int len=strlen(s[6]); for(int i=0;i<len;i++) printf("%c",a[6][i]+'a'); printf("\n\n"); } return 0; }


轉(zhuǎn)載于:https://www.cnblogs.com/jzdwajue/p/7293902.html

總結(jié)

以上是生活随笔為你收集整理的POJ 1449 amp; ZOJ 1036 Enigma(简单枚举)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。