1.题目
问题描述
奇妙的交易X国是一个很特殊的国家,在这个国家的货币只有 V0,V1,V2,...,VnV0,V1,V2,...,Vn 种面值。只要你需要(有这么多钱),你可以让 nn 无限大。同时在这个国家有一个很有趣的拍卖场有一条奇怪的规矩:一次交易中,买卖双方只能对每种面值的货币使用不超过两次。
比如,买一件价格 WW 为198的物品,V=10V=10 的情况,买家可以使用2张 100 (102)100(102) 元纸币,卖家则给出物品和2张 1 (100)1(100) 元纸币。因为奇怪的规则,很多X国人都需要在这个拍卖场交易之前判断一下这个物品是否可以被交易成功。不过很多人并不擅长这种计算,这时候就要请出聪明的你。
输入格式
输入 V,WV,W,代表货币的 VV 和物品的价值 WW。
输出格式
输出 YES 或者 NO 代表是否可以被交易成功。
输入样例
10 9
200 40199
108 50
输出样例
YES
YES
NO
数据范围
- N<100N<100
- V,W<2147483648V,W<2147483648
2.思路
-
初始化:将 V 和 W 分别赋值给变量
n和m。 -
特殊情况处理:如果 V≤5,直接返回 "YES",因为任何小于等于 5 的基数都可以通过不超过两次的使用来表示任意数。
-
模拟交易过程:
- 进入一个循环,直到 m 变为 0。
- 计算 m 对 n 取模的余数
remainder。 - 如果
remainder小于等于 2,说明当前位的货币可以使用不超过两次,直接将 m 除以 n 并继续。 - 如果
remainder大于等于 n−2,说明当前位的货币可以使用一次,并将 m 除以 n 后加 1,表示进位。 - 如果
remainder在 3 到 n−3 之间,说明无法满足使用不超过两次的限制,直接返回 "NO"。
假设
n = 10,m = 198,我们来一步步执行这个模拟过程:-
第一次循环:
m = 198,m % 10 = 8(余数为 8)。8大于等于10 - 2 = 8,因此进入进位处理。将m除以 10,m = 19,然后加 1 得到m = 20。
-
第二次循环:
m = 20,m % 10 = 0(余数为 0)。- 余数小于等于 2,说明可以用 0 张
10面值的货币支付这一位,直接将m除以 10,m = 2。
-
第三次循环:
m = 2,m % 10 = 2(余数为 2)。- 余数小于等于 2,说明可以用 2 张
10面值的货币支付这一位,直接将m除以 10,m = 0。
此时
m变为 0,整个过程结束。结果为"YES"。
假设
n = 108,m = 50,我们来一步步执行这个模拟过程:-
第一次循环:
m = 50,m % 108 = 50(余数为 50)。50不在0 <= remainder <= 2和n - 2 <= remainder之间,因此余数不符合要求,直接返回"NO"。
-
返回结果:如果循环结束后 m 变为 0,说明可以完成交易,返回 "YES"。
3.代码
#include <iostream>
#include <string>
std::string solution(int V, int W) {
// Edit your code here
int n = V, m = W;
if (n <= 5) {
return "YES";
}
while (m != 0) {
int remainder = m % n;
if (remainder <= 2) {
m /= n;
}
else if (remainder >= n - 2) {
m = m / n + 1;
}
else if (remainder >= 3 && remainder <= n - 3) {
return "NO";
}
}
return "YES";
}
int main() {
// Add your test cases here
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;
}