#21539: 使用位元運算的方法


kkmomo (kkmomo)

學校 : 不指定學校
編號 : 29247
來源 : [223.137.94.20]
最後登入時間 :
2024-06-28 12:05:12
d244. 一堆石頭 | From: [118.165.225.11] | 發表日期 : 2020-06-17 01:22

以 bit 的角度看,

可知

1. 在少一個石頭的編號的數字 bit值為1的位置上,所有input在相同bit位置的為1的數總合必定不是 3 的倍數。

2. 在少一個石頭的編號的數字 bit值為0的位置上,所有input在相同bit位置的為1的數總合必定是 3 的倍數。

 

假設input 最大值為2^32 - 1,那麼可以用一個長度為 32 的 array 來記每個bit位置的個數

假設input 最大值為2^64 - 1,那麼可以用一個長度為 64 的 array 來記每個bit位置的個數

 

因為只需判斷個數和是否3的倍數,所以對於每個 bit 只需要 2bits 的大小就足以記錄

假設input 最大值為2^64 - 1,那麼我們就可以利用位元運算的技巧,最多使用 3 個 unsigned log log 的變數來解此題

利用位元運算,設計一個方法 f(x, y) 使計數的 2 bits,每次加 1 時有如此的循環: 00 -> 01 -> 10 -> 00,而沒有增加時,值不變

 

對於每 2bits 使得

f(x, y) : 目前次數為 00<=x<=10 ,增加次數 00<=y <=01

f(00, 00) = 00

f(01, 00) = 01

f(10, 00) = 10

f(00, 01) = 01

f(01, 01) = 10

f(10, 01) = 00

 

假設 0 <=n <= 255

 

a = b = 0

while (let n = input()) != EOF

do

  a = f(a, (n & 0x55)) // 計算奇數位 bit

  b = f(b, (n & 0xAA)) // 計算偶數位 bit

done

print (b + (a >> 1))

 
ZeroJudge Forum