1. 程式人生 > >洛谷P1071(提高組)

洛谷P1071(提高組)

沒有 ott base 提高 字母 行動 相等 code 字母相同

題目描述

R國和S國正陷入戰火之中,雙方都互派間諜,潛入對方內部,伺機行動。歷盡艱險後,潛伏於S國的R 國間諜小C終於摸清了 S 國軍用密碼的編碼規則:

1. S國軍方內部欲發送的原信息經過加密後在網絡上發送,原信息的內容與加密後所得的內容均由大寫字母‘A’-‘Z’構成(無空格等其他字符)。

2. S國對於每個字母規定了對應的“密字”。加密的過程就是將原信息中的所有字母替換為其對應的“密字”。

3. 每個字母只對應一個唯一的“密字”,不同的字母對應不同的“密字”。“密字”可以和原字母相同。

例如,若規定‘A’的密字為‘A’,‘B’的密字為‘C’(其他字母及密字略),則原信息“ABA”被加密為“ACA”。

現在,小C 通過內線掌握了S 國網絡上發送的一條加密信息及其對應的原信息。小C希望能通過這條信息,破譯S國的軍用密碼。小 C 的破譯過程是這樣的:

掃描原信息,對於原信息中的字母x(代表任一大寫字母),找到其在加密信息中的對應大寫字母y,並認為在密碼裏 yx的密字。

如此進行下去直到停止於如下的某個狀態:

1. 所有信息掃描完畢,‘A’-‘Z’ 所有 26個字母在原信息中均出現過並獲得了相應的“密字”。

2. 所有信息掃描完畢,但發現存在某個(或某些)字母在原信息中沒有出現。

3. 掃描中發現掌握的信息裏有明顯的自相矛盾或錯誤(違反 S 國密碼的編碼規則)。例

如某條信息“XYZ”被翻譯為“ABA”就違反了“不同字母對應不同密字”的規則。

在小 C 忙得頭昏腦漲之際,R 國司令部又發來電報,要求他翻譯另外一條從 S國剛剛截取到的加密信息。現在請你幫助小 C:通過內線掌握的信息,嘗試破譯密碼。然後利用破譯的密碼,翻譯電報中的加密信息。

輸入輸出格式

輸入格式:

3行,每行為一個長度在 1100之間的字符串。

1 行為小 C 掌握的一條加密信息。

2 行為第 1 行的加密信息所對應的原信息。

3行為 R國司令部要求小C 翻譯的加密信息。

輸入數據保證所有字符串僅由大寫字母‘A’-‘Z’構成,且第 1行長度與第 2行相等。

輸出格式:

11 行。

若破譯密碼停止時出現 2,3 兩種情況,請你輸出“Failed”(不含引號,註意首字母大

寫,其它小寫)。

否則請輸出利用密碼翻譯電報中加密信息後得到的原信息。

#1樣例:

輸入

AA 
AB 
EOWIE

輸出

Failed

分析:

這道題就是模擬可能情況比較多以前做的時候,翻譯矛盾這個情況還卡了不久(就是太菜了)

先記一遍密文的個數由提議可以知道密文在不重復的情況下字母個數由26個,那我們記個數如果小於26個就直接輸出"Failed".

翻譯矛盾這個情況我們可以先將第一次它的原文和密文對應下一次如果再次同個字母翻譯的情況我們就將這次的翻譯和上次的翻譯對比如果不一樣那麽就是錯誤的我們就直接輸出"Failed".

代碼:

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
string s,s1,s2;
const int N=100+10;
int cnt,cccp[N],cp[N];
char keay[N];
bool judge[N],vis[N],vis2[N];
int main()
{
    cin>>s1>>s2>>s;
    for(int i=0;i<s1.length();i++)
    {
        if(!judge[s1[i]])
        {
            judge[s1[i]]=true;
            keay[s1[i]]=s2[i];
            cnt++;//長度計數
        }
        
    }
    if(cnt<26)//沒有翻譯完這個情況輸出Failed
    {
        cout<<"Failed"<<endl;
        return 0;
    }
    else
    {
        for(int i=0;i<s1.length();i++)
        {
            if(!vis[s1[i]])
            cccp[s1[i]]=s2[i]; 
            else 
            {
                if(cccp[s1[i]]!=s2[i])
                {
                    cout<<"Failed"<<endl;
                    return 0; 
                } 
            } 
            vis[s1[i]]=true; 
        } 
    } 
    for(int i=0;i<s1.length();i++)//正反都要來一次因為可能會重復
    {//即如果A對應B,B對應B這種情況上一步判斷矛盾是判斷不出來的所以我們要反著再來一次
        if(!vis2[s2[i]])
        cp[s2[i]]=s1[i]; 
        else
        {
            if(cp[s2[i]]!=s1[i])
            {
                cout<<"Failed"<<endl;
                return 0; 
            } 
        } 
        vis2[s2[i]]=true; 
    }
    for(int i=0;i<s.length();i++)
    {
        string st;
        st+=keay[s[i]];
        cout<<st;
    }
    return 0;
}

洛谷P1071(提高組)