奇妙货币交易问题

96 阅读2分钟

问题描述

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

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

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


测试样例

样例1:

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

样例2:

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

样例3:

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

问题理解:

你需要判断是否可以通过使用每种面值的货币不超过两次来完成交易。这里的货币面值是 V0,V1,V2,...,即 1,V,V2,V3,...。

解题思路:

通过不断取模和除法操作,判断是否可以在每一步中将 W 分解为不超过两次的每种面值的货币。

具体步骤

取模操作:int remainder = W % V; 计算 W 除以 V 的余数。 条件判断:

  • 如果 remainder > 2,说明当前的余数无法用不超过两次的每种面值的货币凑出,因此尝试调整 remainder 并更新 W。
  • 如果 remainder < -2,直接返回 "NO",因为负数的余数也无法用不超过两次的每种面值的货币凑出。
  • 如果 remainder 在 -2 到 2 之间,直接更新 W。

代码呈现

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
 
using namespace std;
 
std::string solution(int V, int W) {
    if(V==1)
        return "YES";
    while (W != 0) {
        int remainder = W % V;
        if (remainder > 2) {
            remainder -= V;
            W = (W - remainder) / V;
        } else if (remainder < -2) {
            return "NO";
        } else {
            W = W / V;
        }
        if (abs(remainder) > 2) {
            return "NO";
        }
    }
    return "YES";
}
 
int main() {
    std::cout << (solution(10, 9) == "YES") << std::endl;
    std::cout << (solution(200, 40199) == "YES") << std::endl;
    std::cout << (solution(108, 50) == "NO") << std::endl;
    return 0;
}