题意
能不能通过往初始值全为零的v数组中的每一位做操作使得他变成输入的a数组,操作有两种①加上K的i次方(i可以从0开始,i不能有重复)②什么都不做(就是说指定的a数组里面的0项不用管)
思路
将a数组中的所有非0项转成K进制,用一个数组存一下每一种 i 的系数的数量,因为同一个i不能用多次所以当这个值大于1时就输出no
拿样例手动模拟一下
3 9
0 59049 810
0= 0*9^0+0*9^1+0*9^2+0*9^3+0*9^4+0*9^5
59049= 0*9^0+0*9^1+1*9^2+1*9^3+0*9^4+1*9^5
810= 0*9^0+0*9^1+0*9^2+0*9^3+0*9^4+0*9^5
👆 👆 👆 👆 👆 👆
0-----0-----1-----1-----0-----1 每种i的系数的数量
没有超过1的故打印YES
AC代码
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll a[40];//数据很大(10^16)要用long long存
int b[40][64],sum[64];
//b数组用来记录转成K进制后每一种i的系数,sum则是相同i的系数之和(不能超过1)
int main()
{
int t;
cin>>t;
while(t--)
{
memset(b,0,sizeof b);
memset(sum,0,sizeof sum);
memset(a,0,sizeof a);//记得把a也清零第一次没清WA了
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<n;i++)//进制转换
{
ll p=a[i];
int cnt=0;//记录有多少不同的i
if(p!=0)//是0的话直接选择什么都不做就可以变成a数组啦
{
while(p)
{
b[i][cnt++]=p%k;
p/=k;
}
}
}
//将相同i的系数求和(因为对于确切的i,K^i只能用一次,和大于1则不符合要求)
for(int i=0;i<64;i++)
for(int j=0;j<n;j++)
sum[i]+=b[j][i];
int flag=1;//标记是否符合条件
for(int i=0;i<64;i++)
{
//对64做个说明,2^63=9.223372037×10¹⁸>10^16
//64不是一定的60也行只要大于转成K进制后的位数就行
if(sum[i]>1)
{
cout<<"NO"<<endl;
flag=0;
break;
}
}
if(flag)
cout<<"YES"<<endl;
}
return 0;
}