这是出现在Anany Levitin所著的《算法设计与分析基础》第三版习题2.2中的一道算法题:
更轻或者更重?
你有n (n > 2)个外观相似的硬币和一个没有砝码的天平。其中一枚为假币,但不知道它比真币重还是轻。设计一个O(1)的算法来确定假币比真币重还是轻。
解法:
题目只是要求确定假币比真币重还是轻,并不要求找出这枚假币,n的数量不确定(n>=3),在绝大多数情况下只需在天平上比较两次即可知道假币的相对轻重,极端情况也只需三次。
由于n>2,我们分两种情况解决:
情况一:n是3的整数倍。此时可以将这堆硬币按数量等分为三堆,设为A、B、C三堆,假币一定在其中一堆中。
第一次在天平上比较A堆和B堆的重量。分为三种子情况:
a. A与B等重,则A、B堆均为真币,假币一定在C堆中。第二次比较A堆与C堆,若A比C重,则假币比真币轻,否则假币比真币重。
b. A比B重,则C堆一定全为真币,第二次比较A堆与C堆,若A与C等重,则假币在B中且假币比真币轻,若A比C重,则假币比真币重,若A比C轻,则假币比真币轻。
c. A比B轻,同子情况b,C堆一定全为真币,第二次比较A堆与C堆,若A与C等重,则假币在B中且假币比真币重,若A比C重,则假币比真币重,若A比C轻,则假币比真币轻。
情况二:n不是3的整数倍。此时仍然可以将这堆硬币按数量等分为三堆A、B、C,多出来的1~2个硬币先放到一边。
第一次在天平上比较A堆和B堆的重量。也分为三种子情况:
a. A与B等重,则A、B堆均为真币。第二次比较A堆与C堆,若A比C重,则假币一定在C中且假币比真币轻。若A比C轻,假币仍然一定在C中且假币比真币重。若A与C等重,则假币只能在放到一边的多出来的1~2个硬币中,A、B、C三堆均为真币。这种极端情况需要第三次用天平比较,将这1~2枚多出来的币与同等数量的真币比较,若同等数量的真币更重,则假币比真币轻,否则假币比真币重。
b. A比B重,则C堆一定全为真币,假币在A或B中。第二次比较A堆与C堆,若A与C等重,则假币在B中且假币比真币轻,若A比C重,则假币比真币重,若A比C轻,则假币比真币轻。
c. A比B轻,同子情况b,C堆一定全为真币,假币在A或B中。第二次比较A堆与C堆,若A与C等重,则假币在B中且假币比真币重,若A比C重,则假币比真币重,若A比C轻,则假币比真币轻。