題解 古代密碼

2022-05-05 19:42:10 字數 2088 閱讀 3929

古羅馬帝國有乙個擁有各種部門的強大**組織。其中乙個部門就是保密服務部門。為了保險起見,在省與省之間傳遞的重要檔案中的大寫字母是加密的。當時最流行的加密方法是替換和重新排列。

替換方法是將所有出現的字元按照乙個規則替換,比如 abcdefghijklmnopqrstuvwxyz 到 bcdefghijklmnopqrstuvwxyza,如果原詞是victorious則它變成wjdupsjpvt

排列方法改變原來單詞中字母的順序。例如:將順序 \(\left<2,1,5,4,3,7,6,10,9,8\right>\) 應用到victorious上,則得到ivotcirsuo

人們很快意識到單獨應用替換方法或排列方法加密,都是很不保險的。但是如果結合這兩種方法,在當時就可以得到非常可靠的加密方法。所以,很多重要資訊先使用替換方法加密,再將加密的結果用排列的方法加密。用兩種方法結合就可以將victorious加密成jwpudjstvp

考古學家最近在乙個石台上發現了一些資訊。初看起來它們毫無意義,所以有人設想它們可能是用替換和排列的方法被加密了。人們試著解讀了石台上的密碼,現在他們想檢查解讀的是否正確。他們需要乙個電腦程式來驗證,你的任務就是寫這個驗證程式。

輸入有兩行。

第一行是石台上的文字 \(s\)。文字中沒有空格,並且只有大寫英文本母。

第二行是被解讀出來的加密前的文字 \(t\)。第二行也是由大寫英文本母構成的。

如果第二行經過某種加密方法後可以產生第一行的資訊,輸出yes,否則輸出no

測試時間限制 \(1000\ \mathrm\),空間限制 \(512\ \mathrm\)

這道題的關鍵就是要抓住不變數來解決問題。

注:設 \(n\) 與 \(|s|\),\(|t|\) 同階。

很簡單,就是列舉 \(26\) 種情況,然後列舉所有排列,看看有沒有重合的。

複雜度:\(\theta(n\times n!)\)

這也很簡單,只要列舉 \(26\) 種情況,分別排序並核對即可。

複雜度:\(\theta(n^2\log n)\)

如果此題的資料範圍提公升到 \(n\le 10^5\),還有沒有方法做呢?

答案是有的。關鍵是我們要學會抓住不變數。

注意到兩個方法會對原串修改,但是這個修改是有跡可循的。

比如說,字元排列的不變數就是字元集合(這裡的集合是多重集合,也就是說可以有重複元素)。

同時,按照規則替換不變的就是固定字元出現的數量。

比如,abcddeee無論怎麼改,必然有乙個字元出現三次,有乙個出現兩次,而還有三個字元各出現一次。

注意到,字元集合不變也意味著固定字元出現的數量不變。

那麼,我們能不能就此判斷固定字元出現次數不變就是評判標準呢?

nonono,我們還要證明,對於所有的固定字元出現次數不變的情況,必然會存在一種操作方法,使得這兩個字串可以互相轉化。

其實很簡單。我們只要證明存在乙個字串 \(a\),使得 \(s\) 可以通過交換法則得到 \(a\),且 \(a\) 的字符集與 \(t\) 對應。

因為固定字元出現次數不變,我們只要對其出現次數排序則兩個數列必然相同。讓對應的字元轉換即可。

這樣,我們就能夠在 \(\theta(n+|u|\log |u|)\) 內完成問題,其中 \(u\) 是字符集。

這裡的寫法用的是最後一種方法,還是比較快的。

#include #include using namespace std;

const int max_n = 100, max_charset = 26;

char s1[max_n+1], s2[max_n+1];

int cnt1[max_charset] = {}, cnt2[max_charset] = {};

int main()

puts("yes");

return 0;

}

這道題很水,但是我們可以試圖找到更有意思的做法來增加難度。

同時,我們也要在不確定時用證明來給出答案。

POJ古代密碼

include include include include using namespace std 排列時可以任意換位置,所以位置是無所謂的,只要字元能對應即可。字元的變換規則是乙個字元對應另乙個字元。如果第乙個字串中某個字元出現了四 次,第二個字串中沒有出現過四次的字元,則一定不可能變換成功。...

題解 lg2480 古代豬文

給定整數 q,n 1 leq q,n leq 10 9 求 q c mod 999911659 首先由擴充套件尤拉定理可知,因為999911659為質數 q c equiv q c mod 999911658 mod 999911659 設 x sum c mod 999911658 然後再 由於 ...

題解 SDOI2010 古代豬文

原題傳送門 poi和pku是真的流批 這是一篇晚來十年的題解.洛谷 題目太長,這裡直接給出 演算法競賽高階指南 的題面 給定整數 q,n 1 leqslant q,n leqslant 10 9 計算 q c n d mod 而這到題裡,我們用 g 表示 q 首先給出乙個特例 當 g 9999116...