题目解析:奇妙货币交易问题 | 豆包MarsCode AI刷题

121 阅读2分钟

问题描述

小R住在一个名为 X 国的国家,这里的货币非常特殊,面值为 V0V^0,V1V^1,V2V^2,...,VnV^n,并且 n 可以无限大。该国的交易规则也很特别:在一次交易中,双方只能对每种面值的货币使用不超过两次。

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

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

测试样例

样例1:

输入:V = 10,W = 9
输出:'YES'

样例2:

输入:V = 200,W = 40199
输出:'YES'

样例3:

输入:V = 108,W = 50
输出:'NO'

思路分析

首先理解一件事,题目中 V0V^0,V1V^1,V2V^2,...,VnV^n 可以表示 V 进制的位权,任意一个整数都可以被 V 进制唯一表示。也就是说,我们可以把W用V进制唯一表示,但是题目中每一个面值的货币数量取值范围都是 [2,2][-2,2] 的整数,而进制的表示中是不会有负数的。

那这个问题怎么解决呢?我们可以先确定W用V进制表示的位数,然后遍历每一个 ViV^i ,让 W += 2 * V_i ,此时每一个面值的货币数量取值范围就变成 [0,4][0,4] 的整数。我们将新的 W 用 V 进制唯一表示,就可以得到每一种货币需要的数量,如果其中某一位的数值大于4的话,就说明不能按照规则用给定的货币面值 V 来完成价格为 W 的交易。

代码实现

def solution(V, W):
    if V <= 4:
        return "YES"

    V_n = [1]
    W += 2
    while W / V_n[-1] >= V:
        V_n.append(V_n[-1] * V)
        W += 2 * V_n[-1]
    V_n.reverse()
    for V_i in V_n:
        if W // V_i > 4:
            return "NO"
        W = W % V_i

    return "YES"

V <= 4 时,每一位的数值都不会超过4,一定可以完成交易。

其他情况下,找出 W 表示成 V 进制需要的位数,并且还要在这个过程中对每一位使 W 增加 2 倍的位权。然后就可以计算 W 用 V 进制表示每一位的值,如果某一位的值大于4,直接返回 "NO",如果每一位都可以在 4 以内表示,就可以返回 "YES"

复杂度分析

时间复杂度 O(logVW)O(log_V W)