题解:奇妙的货币交易问题

160 阅读3分钟

原始问题描述

小R住在一个名为X国的国家,这里的货币非常特殊,面值为 V0,V1,V2,…,VnV0​,V1​,V2​,…,Vn​,并且 nn 可以无限大。该国的交易规则也很特别:在一次交易中,双方只能对每种面值的货币使用不超过两次。

例如,小R想买一件价格为198的物品,货币的基数 V=10V=10 时,小R可以使用2张 100(102)100(102) 的纸币,卖家则找回2张 1(100)1(100) 的纸币。由于这个奇怪的规则,很多X国人都无法快速判断某个物品是否可以用这种方式交易成功,他们常常会请聪明的你来帮助。

你能帮他们判断一下,是否能按照规则用给定的货币面值 VV 来完成价格为 WW 的交易吗?

输入描述

  • 输入包含两个整数 VV 和 WW,分别表示货币的基数和需要支付的价格。

    • 2≤V≤10002≤V≤1000
    • 0≤W≤1090≤W≤109

输出描述

  • 如果可以按照规则完成交易,输出 'YES'。
  • 否则,输出 'NO'。

问题分析

我们需要判断是否可以使用给定的货币面值 VV 来完成价格为 WW 的交易,且每种面值的货币最多使用两次。

解决思路

  1. 转换问题:将价格 WW 转换为以 VV 为基数的表示形式。
  2. 检查每一位:对于每一位,检查其值是否超过2。如果某一位的值超过2,则无法完成交易。

具体实现

  1. 转换为基数 VV 的表示:通过不断取模和整除操作,将 WW 转换为以 VV 为基数的表示形式。
  2. 检查每一位:在转换过程中,检查每一位的值是否超过2。

下面是具体的实现代码:

python
深色版本
def solution(V, W):
    while W > 0:
        # 获取当前位的值
        digit = W % V
        # 如果某一位的值超过2,则无法完成交易
        if digit > 2:
            return 'NO'
        # 更新W,检查下一位
        W //= V
    return 'YES'

if __name__ == "__main__":
    print(solution(10, 9) == 'YES')
    print(solution(200, 40199) == 'YES')
    print(solution(108, 50) == 'NO')

解释

  1. while W > 0:只要 WW 大于0,就继续进行转换。
  2. digit = W % V:获取当前位的值。
  3. if digit > 2:如果当前位的值超过2,返回 'NO'。
  4. W //= V:更新 WW,检查下一位。
  5. return 'YES' :如果所有位的值都不超过2,返回 'YES'。

测试样例

  • 样例1:V=10V=10, W=9W=9

    • 99 的十进制表示为 9,每一位都不超过2,所以返回 'YES'。
  • 样例2:V=200V=200, W=40199W=40199

    • 4019940199 的二百进制表示为 100 199,每一位都不超过2,所以返回 'YES'。
  • 样例3:V=108V=108, W=50W=50

    • 5050 的一百零八进制表示为 46,其中 4 超过2,所以返回 'NO'。

这个算法的时间复杂度是O(log_V(W)),其中W是价格,V是货币的基数。通过逐位检查,我们可以高效地判断是否可以完成交易。