Suppose you are performing the following algorithm. There is an array v1,v2,…,vnv1,v2,…,vn filled with zeroes at start. The following operation is applied to the array several times — at ii -th step (00 -indexed) you can:
- either choose position pospos (1≤pos≤n1≤pos≤n ) and increase vposvpos by kiki ;
- or not choose any position and skip this step.
You can choose how the algorithm would behave on each step and when to stop it. The question is: can you make array vv equal to the given array aa (vj=ajvj=aj for each jj ) after some step?
The first line contains one integer TT (1≤T≤10001≤T≤1000 ) — the number of test cases. Next 2T2T lines contain test cases — two lines per test case.
The first line of each test case contains two integers nn and kk (1≤n≤301≤n≤30 , 2≤k≤1002≤k≤100 ) — the size of arrays vv and aa and value kk used in the algorithm.
The second line contains nn integers a1,a2,…,ana1,a2,…,an (0≤ai≤10160≤ai≤1016 ) — the array you'd like to achieve.
For each test case print YES (case insensitive) if you can achieve the array aa after some step or NO (case insensitive) otherwise.
5 4 100 0 0 0 0 1 2 1 3 4 1 4 1 3 2 0 1 3 3 9 0 59049 810
YES YES NO NO YES大意是给定目标序列,问从起始序列(全0)能否经过若干步操作到达目标序列。对于第i次操作,可以啥都不干也可以给 某个数加上k的i次方。考虑到可以什么都不干,且每次增加的数彼此互不相同,可以这么想:尝试把目标序列的每个数拆分成若干个k的次方(彼此互不相同)的和的形式(类似二进制拆分)如a[i]=k^p1+k^p2+....k^pn(p1!=p2!=...pn),如果不能成功拆分的话直接就能判定不能到达。然后对于每个数把其p1...pn放进一个vector然后sort,如果有两个数彼此相等则不能到达(每次操作加的数都不一样),反之可以。详情见注释。
#include <bits/stdc++.h>
using namespace std;
int n,k;
long long ori[35],a[35];
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>k;
memset(a,0,sizeof(a));
int i;
vector<int>v;
for(i=1;i<=n;i++)
{
scanf("%lld",&ori[i]);
}
bool flag=1;
for(i=1;i<=n;i++)
{
long long temp=ori[i];
int cnt=0;
if(ori[i]==0)//为0则不需要任何操作
{
continue;
}
while(temp)//拆分
{
if(temp%k!=0&&(temp-1)%k!=0)//代表不能拆成k的次方和的形式
{
flag=0;
break;
}
if((temp-1)%k==0)//有k的0次方
{
v.push_back(cnt);//把当前累积的变量扔进去
temp--;//减去1
cnt++;
temp/=k;
}
else if(temp%k==0)
{
cnt++;
temp/=k;
}
}
if(!flag)break;
}
if(!flag)//必须要先判断这个
{
cout<<"NO"<<endl;
continue;
}
if(!v.size())//flag不为0的情况下如果vector是空的
{
cout<<"YES"<<endl;
continue;
}
sort(v.begin(),v.end());
for(i=0;i<v.size()-1;i++)
{
if(v[i]==v[i+1])//判重复
{
flag=0;
break;
}
}
if(!flag)
{
cout<<"NO"<<endl;
continue;
}
else cout<<"YES"<<endl;
}
return 0;
}
来源:https://www.cnblogs.com/lipoicyclic/p/12453200.html