Python 板


LINE

※ 引述《Anisno (Anisno)》之銘言: : 我遇到一個問題,題目如下:給一個正整數,你必須找出遮罩M,滿足L<M<U且N or M : 運算後數字最大。 : 假如 : N=30951344 : L=201310 : U=3567891 : 求M=___ 要解的話最簡單就是 NM, M = max((i|N, i) for i in range(L+1,U)) 出來 NM 就是 N or M 值,M 即所求 不過這樣複雜度是 O(U-L) 我想到一個 O(log(U)) 的解法 以範例來說 U-L = 3366581 log(U) = 21.8 效率差距差不多就差這麼多 我想到的解法是 找出所有 "介於 U L 間,盡量多 1 或是盡量越大的數字" 稱為 candidates 再從這些 candidates 中取出跟 N 做 or 最大者 實作出的 code 有點長,我直接加註解傳到貼 code 網站 http://ideone.com/p0YzSV 建意看以下的演算法可以搭配 code 會比較清楚 :) class Entry 欄位解釋: (等等演算法中 queue 裡的元素都是 Entry) M: 現在的 M 值,是 binary string 型式,是從高位元填下來的 uf: upperbound flag: 有 set 表示現在的 M 值已保證小於 U lf: lowerbound flag: 有 set 表示現在的 M 值已保證大於 L idx: 現在跑到第幾 bit (最高位元是 idx=0) 在開始前,先把 U L 轉成 binary string 而且長度對齊,L 短的部份就前面補 0 以下的 length = len(U) = len(L) # code 中 ub lb 是指 binary string 版的 U L 演算法 ====== 主要的概念就是從最高位元(idx=0)開始填 0/1,然後再往下走 idx=1 填 0/1 如此一來會展開一顆二元樹,葉子會有 2**length 個 然後我們用 BFS 去走訪他,搭配剪枝可以砍掉大部份的狀況 # DFS 應該也可以,不過我 code 是用 BFS 實做的,效能應該差不多 剛剛提到的 class Entry 可以想成是在每個節點的 狀態 在每次 main while 跑時會從 queue 中取一個狀態來走,然後把新的狀態加到 queue 中 若取出的狀態,發現 lf uf 都已 set 了,表示已符合 L<M<U 那麼後面亂填也不會影響到 L<M<U,跟據題意當然全填 1 這樣 or 起來會最大 class Entry 的 get() 就是在後面補 1 用的,然後結果就會是一個 candidate 若取出的狀態,發現 idx >= length,表示 M 的長度已經填滿了 表示 尋找 L<M<U 失敗,那這條路就不理他 (continue) 再來就是演算法的重點,要怎麼作狀態轉移 跟據 U[idx] L[idx] 的值會有 4 種狀況:00 01 10 11 我跟據等等解釋需要做一點順序的調整 U L 1. 1 0 2. 0 1 3. 0 0 4. 1 1 U L 1. 1 0 在這個狀況下 M 若填 1 就 "一定保證比 L 大" -> set lf M 若填 0 就 "一定保證比 U 小" -> set uf 因此會產生兩個新狀態:"填 1 並 set lf" "填 0 並 set uf" 這裡,我們不能知道 填1比較好 還是 填0比較好 因為 set 的 flag 不同(set flag 可以想成是得到的保證) 後面可能會有不同結果 U L 2. 0 1 這個狀況比較神奇,因為 U > L 若在前面的 bit 全部都 U==L,那到這位發現 U[idx]==0 L[idx]==1 就不合前題 (因為我們是從高位走下來的) 因此會遇到這個狀態只有可能是前面出現過 1 0 (狀況1) 既然出現過 狀況1,那 lf 或 uf 一定有其中一個被 set 所以分狀況 if lf is set: (已經保證比L大了) 為了滿足 M<U,這裡一定要填 0 if uf is set: (已經保證比U小了) 為了滿足 M>L,這裡一定要填 1 if lf ul are not set: 不可能出現 在這個狀況下,由於要滿足 L<M<U,只會產生一個新狀態,而不會動到 flag U L 3. 0 0 這個狀態必需要考慮到 uf,因為 M<U,隨便填 1 的話可能會因此 M>U if uf is not set: 為了不能讓 M 超過 U,只能填 0 if uf is set: M 已經保證小於 U 了,這位可以高興的直接填 1 順便 set lf -> uf lf 皆 set,結束這條路 (後面也可以高興的全填 1) U L 4. 1 1 這個狀態與上個類似,因為 M>L,所以必需看 lf 行事 if lf is not set: 為了不能讓 M 小於 L,只能填 1 if lf is set: M 已經保證大於 L 了,這位...填 0 填 1 都可以 填 0 --> set ul 結束這條路 填 1 --> 什麼 flag 都不會動,繼續做 為什麼不能像 狀況3 直接結束這條路呢? 因為 N[idx] 有可能在這位是 0,那麼這位填 1 可能會得到 N or M 比較大 當然可以判斷 N 值多砍一點,不過現在效能已經改善很多,先不弄這麼複雜 如此去走訪這顆樹,走完後會一堆 candidates 再一個個去測誰和 N or 起來最大就結束了 # 當然可以在一產生 candidate 時就做 N or M 然後記錄最大 # 這樣可以再省掉存 candidates 花的時間和空間,不過這跟演算法沒什麼關系 # 為了方便我就先沒這樣寫了XD ----------------------------------------------------------------- 效能的部份 這個方法最壞就是整顆樹走完 O(U),不過這是不可能的事 由於剪枝的關系,每往下一層大約只有 2 條路能走到 (沒剪枝是 2**層數 條) 雖然沒精算,不過我覺得效能差不多是 O(2*log(U)) = O(log(U)) 而實測也差不多是如此 範例的 U=3567891 L=201310 爆搜要 3567891 - 201310 跑 3366581 次 但用這個演算法 main while 只跑了 37 次,產生的 candidates 只有 12 個 2*log(3567891) = 43.5 差不多再少一點這樣 程式是用 python2 寫的,從 stdin 依序讀入 U L N 要改 python3 只有 print 和 raw_input 需要動 這個實作是把數字轉成 0/1 組成的 string 做的 真的要加速的話可以直接用 bitwise,但這部分與演算法無關就不提了 有問題或 bug 歡迎提出 :) -- 光明 的背後 是 黑暗 黑暗 的背後 還是 黑暗 由此可知 黑暗 > 光明 Q.E.D. --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.113.235.135 ※ 編輯: darkgerm 來自: 140.113.235.135 (11/05 22:47) ※ 編輯: darkgerm 來自: 140.113.235.135 (11/05 22:52)







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Boy-Girl站內搜尋

TOP