刷题-奇妙货币交易问题 | 豆包MarsCode AI

232 阅读3分钟

问题描述

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

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

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


测试样例

样例1:

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

解析: 本题可以采用贪心的思想, 先将小于W的面值遍历,之后将W从大到小依次减去这些面值,看最后是否能组成0。注意,题目的意思不是买家用货币组成价格W,而是由双方出钱的差值组成W。因此本题我采用gap表示双方出钱的差值,遍历面值使得gap的绝对值越来越小逼近于0,这样就可以成功判断了。 主要功能是判断是否存在一个整数 V 的幂次可以通过加减运算得到目标值 W。具体步骤如下:

  1. 初始化一个列表 value,并将 1 添加到列表中。
  2. 判断 V 是否等于 1,如果是,则直接返回 "YES",因为任何数的 1 次幂都是它本身。
  3. 如果 V 不等于 1,则进入一个循环,不断将列表中最后一个元素乘以 V,并将结果添加到列表中,直到列表中的最后一个元素大于或等于 W
  4. 初始化一个变量 gap,表示当前值与目标值 W 的差距。
  5. 进入一个从列表最后一个元素开始的循环,尝试通过加减列表中的元素来缩小 gap
  6. 在循环中,分别尝试减去和加上列表中的元素,并更新 gap 为新的差距。
  7. 如果在某次尝试后 gap 变为 0,则返回 "YES",表示可以通过加减运算得到目标值。
  8. 如果循环结束后 gap 仍然不为 0,则返回 "NO",表示无法通过加减运算得到目标值。

总结来说,这段代码通过生成一个整数 V 的幂次数列,并尝试通过加减运算来达到目标值 W,从而判断是否存在这样的解。

作者:用户487392561163
链接:juejin.cn/spost/74384…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

def solution(V, W):
    # Edit your code here
    
    value = []
    value.append(1)
    if V == 1:
        return "YES"
    while value[-1] < W:
        value.append(value[-1]*V)
    gap = W
    for i in range(len(value)-1, -1, -1):
        oldgap = gap
        if abs(oldgap - value[i]) < abs(oldgap):
            gap = oldgap - value[i]
            if abs(gap - value[i]) < abs(gap):
                gap = gap - value[i]
        if abs(oldgap + value[i]) < abs(oldgap):
            gap = oldgap + value[i]
            if abs(gap + value[i]) < abs(gap):
                gap = gap + value[i]
        if gap == 0:
            return "YES"
    return "NO"
    
if __name__ == "__main__":
    # Add your test cases here
    print(solution(10, 9) == "Yes")
    print(solution(200, 40199) == "Yes")
    print(solution(108, 50) == "NO")