ny 744 螞蟻的難題 一 位運算

2021-07-05 01:50:34 字數 1859 閱讀 8790

時間限制:

1000 ms  |  記憶體限制:

65535 kb

難度:2 描述

小螞蟻童鞋最近迷上了位運算,他感覺位運算非常神奇。不過他最近遇到了乙個難題:

給定乙個區間[a,b],在區間裡尋找兩個數x和y,使得x異或y最大。來,幫幫他吧!

輸入

有多組測試資料(以eof結尾)。

每組資料輸入兩個數a,b.(0<=a輸出

輸出a到b之間,異或最大的值。

樣例輸入

1 2

8 9

樣例輸出

3

1

第一次見到這個題的時候,感覺有技巧,但是自己沒有想到,後來看了別人的提示,想明白了,然後a 了,但是這麼簡單的題還有必要再多說嗎?有!

因為看了網上的**,雖然他們的**都不錯,但是解釋的都不對,至少自己看了好幾個人寫的所謂規律,沒有乙個是對的,說錯了,不是規律不對,而是表達不對,反正不知道他們是怎麼做出來的,或者說是他們在看了別人的**之後是直接a掉的,也沒仔細想,反正我是想了,以下是個人的一些見解,也許會被另外的人說不正確,但是個人認為還是沒有問題的:

先說異或的規則:

按位進行異或,那麼兩個數的運算結果每一位滿足同零異一,也就是,每一位相同的話,結果這一位是 0 否則是 1 ,然後看二進位制的組成結構,因為二進位制逢二進一,只有0 或者 1 來表示,那麼在相鄰的兩個數中,這兩個數的最後一位肯定是交替出現0 或者 1 ,類似的也有相似的情況,這裡留給大家去研究,下面就是需要**的問題了,為了異或得到的值最大,那麼首先位數要高,那麼肯定優先選舉位數最大的數,也就是給出的最大的數以及位數相同的幾個數,當然,他們只能有乙個最優的,只是先定性分析一下,相同的,也盡量選位數最小的乙個,呵呵,如果是 0 ,那麼就更好了,但是..可惜不是你~所以 只能選擇乙個位數最小的幾個數了,最小的數,位數肯定不會比某個數的大吧,最大的數,位數也不會比某個數小吧?那麼這就對了!選擇這兩個為代表,先求出來這個最優的結果最多有幾位!為什麼這裡可以求出來最高有幾位呢?還是很好想的,因為最大的數的 1 肯定想對別的數比較集中在前面,比較小的相對於集中在後面,這樣異或下去,雖然不是最優值,但是已經盡量避免了較高位被消去(相同為零),那麼求出的數值肯定是和最優解是相同位數的!

然後下面就是其他人理解的規律了,說的不錯,因為相鄰(或者相差某些二進位制位數)的數的 0 和 1 的位置是交替出現的,那麼完全可以稍微調整較大和較小的位置來使得異或的結果出現 11111...1111(b),的情況,比如1000(b) 和10(b),他們中的數異或的最大值,位數最多肯定是四位 ,8 的最後一位是 0 ,那麼,我們可以把 2 增加一,達到了值變大的目的,然後發現,還可以再把 2 增大一位,變成 7 ,這樣就取得最大值了(這個例子只討論了增大的情況,減小也一樣,比如 10 和 2 ) ,不難發現,只要是在位數限制範圍內,通過移動,可以實現所有的位置異或的結果出現 1 ,這也就是最後的規律了,然後這個結果可以借助二進位制位數來實現,也就是別人所說的 2的n次方 減去 1 ,不過n代表的是最優結果的位數,而不是其他人說的最大值的位數!因為最優解不一定具有和最大值相同的位數,比如 8 9 ,他們異或的最大位數是 1 ,那些隨便寫部落格的人,自己都沒真正理解別人的這個做法的由來和原因,完全是照搬別人的**和解釋,也是醉了.......

個人不反對參考別人的思路和解析,但是一定要有自己的理解,如果自己沒理解,非要照著別人的寫和說的話,無異於自欺欺人,對自己並沒有什麼用處...個人也是菜鳥,但是自己按著自己的方法來學,會就是會,不會就是不會,這樣才是對自己負責的心態....

吐槽結束了.....

有欠缺的地方,希望大家指正!

#includeint main()

printf("%lld\n",maxn-1);

} return 0;

}

nyoj744 螞蟻的難題 一

時間限制 1000 ms 記憶體限制 65535 kb 難度 2 描述 小螞蟻童鞋最近迷上了位運算,他感覺位運算非常神奇。不過他最近遇到了乙個難題 給定乙個區間 a,b 在區間裡尋找兩個數x和y,使得x異或y最大。來,幫幫他吧!輸入 有多組測試資料 以eof結尾 每組資料輸入兩個數a,b.0 a輸出...

一 位運算的奇巧淫技

補充 異或,可以理解為不進製加法 1 1 0,0 0 0,1 0 1 性質 1 交換律,可任意交換運算因子的位置,結果不變 2 結合律 即 a b c a b c 3 對於任何數x,都有x x 0,x 0 x 4 自反性a b b a 0 a,連續和同乙個因子做異或運算,最終結果為自己 題1 找出唯...

嵌入式linux C語言(一) 位運算的使用

嵌入式linux c語言 一 位運算的使用 arm是記憶體與io統一編址,soc中有很多控制暫存器,通過對這些暫存器進行位運算對這些控制暫存器進行設定,進而控制外設功能。在修改暫存器某些位的過程中不能修改其他的位。c語言基本的位操作符有與 或 異或 取反 左移 右移六種位運算子。如下表所示 符號描述...