链接:https://ac.nowcoder.com/acm/contest/910/E

题目描述


现在有很多砝码,质量为w的0次方、1次方……n次方,每个砝码都只有一个。还有一个天平,可以在两端放置砝码和重物。现在要用这些砝码搭配出相等于重物的质量m,也可以把若干个砝码和重物一起放在天平的一侧,来平衡这个天平。

输入描述:

第一行为一个整数T,代表有T组数据

接下来T行,每行有两个整数w,m (2 ≤ w ≤ 10^9, 1 ≤ m ≤ 10^9)。

输出描述:

如果能,输出YES,否则输出NO。

示例1

输入

2
3 7  
4 22

输出

YES
NO

备注:

对第一组样例,可以将重物和质量为3的砝码放到一个托盘中,质量为9和1的砝码放到另外一个托盘中。

第二组样例无论怎么搭配砝码和重物,也无法使天平两端达到平衡。

解题思路:


毫无头绪。。。看了大佬们ac的代码还是不懂,后来看了真正的题解才懂了(;´༎ຶД༎ຶ`)

看到w的0次方、1次方……n次方,可以想到w进制,把m转化为w进制,记为M,如果M加一些w的次方使得最后M的每位不是1就0,那么最后每位不是0就是1的M,就可以由一些w的次方组合成M,这就相当于天平的一边。

拿第一个样例来说吧:w=3,m=7,m写成3进制后即M=21,从末尾往前遍历,最末尾是1不用动,倒数第二位是2(2=3-1),所以M再加上3的1次方进位之后就变成了101,这样就可以知道天平的一边是3^2+1(即101(3)转换为10进制),另一边是7+3

但是需要注意的是如果M某位上的数字不是0也不是1时,只有当它是w-1才能从w的0次方、1次方……n次方选一个,然后进位,如果它不是w-1的话根据题目条件每个砝码只有一个,那么M就不能变成最终只含有1或0的数了,这样的话就要输出N0

综上,正解思路为:

将m转化成w进制,然后从小的位数开始遍历一遍如果为0或1不进行操作,如果为w-1则加上一个数使得当前位数变成0,如果为其他数着就可以直接输出NO,如果没有输出NO 则最后输出YES

 

ac代码:


#include <iostream>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <fstream>
#define  maxn 100
#define lowbit(x) (x&(-x))
typedef long long ll;
const ll mod=1e9+7;
using namespace std;
ll t,w,m,a[maxn];
int main()
{
    scanf("%lld",&t);
    while(t--)
    {
        memset(a,0,sizeof(a));//注意清空,否则第41行的代码可能会受影响,会wa掉
        bool flag=false;
        ll num=0;
        scanf("%lld %lld",&w,&m);
        while(m)//把m转换为w进制的数
        {
            a[num++]=m%w;
            m/=w;
        }
        for(ll i=0;i<num;i++)
        {
            if(a[i]==0 || a[i]==1) continue;
            else if(a[i]==w-1)//选择一个w的i次方模拟进位
            {
                ll index=i+1;
                ll carry=1;//进1
                a[i]=0;
                while(carry)
                {
                    a[index]+=carry;
                    carry=a[index]/w;
                    a[index]%=w;
                    index++;
                    if(index > num) num=index;//进位之后总位数变大
                }
            }
            else
            {
                flag=true;
                break;
            }
        }
        if(flag) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}