题目链接:
[CodeForces 552C]Vanya and Scales[math]
题意分析:
给出w^0、w^1~w^100和m,问:能否用这些w的值进行加减,组成m。
解题思路:
将m变成w进制的,然后从低位往高位扫描,设当前位为i位,那么:如果该位是0,则不管;如果是1,则减去w^i;如果是w - 1,则加上w^i,此时高位进1;如果是w,直接进位;那么在1~w - 1之间的数字的话怎么办?可以肯定,此时就是无法表示的。
假设当前w为7,当前需要判断的数字是150000(7),到达5时,考虑下能否把这一位变成7或者0。首先,该位的w没用过,所以我们可以让5加1或者减1,这里明显5离7比较近,所以我们选择加1变成6,那么剩下的1哪里来呢?前面的砝码都没有用过,将这些砝码用等比求和相加,发现:当公比大于1时,前n项和小于第n+1项,所以无法构成缺少的1。那么后方的砝码与前方的砝码结合呢?确实可以考虑,不过这样又会使得5前面的0变成了6,而前方砝码被使用了,注定这个6填不成7。综上,我们得出上述结论。
个人感受:
(⊙0⊙)
具体代码如下:
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<string>
#define pr(x) cout << #x << " = " << (x) << '\n';
using namespace std;
const int MAXN = 111;
int num[MAXN];
int main()
{
int w, m;
while (cin >> w >> m) {
int top = 0;
int x = m;
while (x) {
num[top++] = x % w;
x /= w;
}
num[top] = 0;
bool ok = 1;
for (int i = 0; i <= top; ++i) {
if (num[i] != 0 && num[i] != 1 && num[i] != w && num[i] != w - 1) {
ok = 0;
break;
}
if (num[i] == w || num[i] == w - 1) ++num[i + 1];
}
if (ok) cout << "YES\n";
else cout << "NO\n";
}
return 0;
}