dex國剛剛截獲了kcaj國與awaw國之間的s.message 。d國s302情報機構情報員007 手裡正拿著寫有k國與a國之間message的檔案。「什麼?!居然被加密了!!」007忍不住說道,「kcaj,你會出路的!」
幸運的是k國與a國此次通訊時間遠遠超過了007所估計的30s,因此007又截獲了大量的message。通過對這些message的研究,007發現了其中的秘密:
每一條s.message原本由8個32-bit的正整數n1..n8組成,本來這8個整數可以由計算機直接破解得出相應的文字。但對於每條資訊,k國與a國另外使用了不同的金鑰m來再次加密。所謂「金鑰」其實也是乙個32-bit的整數,在傳遞訊息的時候,是將n1 xor m、n2 xor m、…、n8 xor m、n9 xor m這9個整數傳給對方(其中n9為n1~n8這8個整數的和mod 2^32)。
有了上面的發現,007馬上意識到他可以破解出message了!這實在是乙個簡單的工作,007決定讓你——也就是他的助手來完成此工作。
輸入檔案按順序輸入9個整數n1..n9。每個整數用16進製表示。
輸出僅乙個數,即金鑰m。同樣用16進製表示。
3 4 4 7 7 b a 2 2e
6【資料範圍】
40%的資料滿足m<=500;
100%的資料滿足m<2^32;
出題意圖:
遞推題幾乎也是分割槽聯賽的必考題,本題考察選手運用遞推思想解題的能力。
簡要解答:
本題目的是求出m,換言之只要確定m轉換成二進位制後每一位是0還是1即可。
首先我們把32-bit整數二進位制位從低位到高位編號為第1位到第32位;
設輸入的9個整數為a[1]..a[9],即a[1]=n1 xor m,a[2]=n2 xor m……a[9]=n9 xor m;
a[i,j]=0或1,表示a[i]轉化為2進製後第j位上的數字, 之後類似做豎式加法. 那麼如何遞推呢?從低位到高位,顯然,低位一確定即不會改變。
顯然我們需要列舉m的第i位數字是0還是1:
設m的第i位數字是0:
在確定第i位之前,m的前i-1位已確定,即前i-1位已正確驗證。我們設m的i位數字是0,對所a1到a8與設定的m異或並取出前i位求和得到原始值的前i位累加和,如果該和的前i位與a9對m異或並取出的前i位相等,好麼等式成立,m第i位為0,繼續遞推,否則,第i位為1並修改m。
最後輸出m即可.
說人話就是推第i位時候,如果m此時是0則這一位什麼數字都不會變,我們就把上乙個m拿來加一下,如果前i位是相同的就是0,反之就是1
code:
1 #include2 #include3using
namespace
std;
4int
main()
13if((sum&mask)!=((a[9]^m)&mask))
14 m+=(1
<16 printf("%x"
,m);
17return0;
18 }
over
力扣67 二進位制求和(逐位運算 位運算)
力扣67.二進位制求和 給你兩個二進位制字串,返回它們的和 用二進位制表示 輸入為 非空 字串且只包含數字 1 和 0。示例 1 輸入 a 11 b 1 輸出 100 示例 2 輸入 a 1010 b 1011 輸出 10101 每個字串僅由字元 0 或 1 組成。1 a.length,b.leng...
10 17T4 位置前字尾 map查詢
給出1 n的乙個排列,統計該排列有多少個長度為奇數的連續子串行的中位數是b。中位數是指把所有元素從小到大排列後,位於中間的數。第一行為兩個正整數n和b 第二行為1 n 的排列。輸出乙個整數,即中位數為b的連續子串行個數。輸入1 5 41 2 3 4 5 輸入2 6 31 2 4 5 6 3 輸入3 ...
5分鐘了解位運算
運算子分為6種,它們是 名稱符號 按位與 按位或 按位異或 按位取反 左移運算 右移運算 按位與運算將參與運算的兩數對應的二進位制位相與,當對應的二進位制位均為 1 時,結果位為 1,否則結果位為 0。按位與運算的運算子為 參與運算的數以補碼方式出現。舉個例子,將數字 5 和數字 8 進行按位與運算...