C. Adding Powers
题意:
给你一个目标数组,要你 对一个所有元素从0开始的数组 进行一种操作。
- 每一步可以对一个元素增加 k^i ( i 为每一步)( i 可以为0)
- 或者第 i 步不进行操作
思路(贪心):
既然每一步的元素只能用一次,或者不用,而又是k次幂。
所以对最大一个考察时,应该满足一个条件:
- 最大的元素只能由比它小的 k次幂来构成
(等比数列第n项和前n-1项和有一个关系:
sum(n-1)< k^n,我做的时候想到这个结论,不过没用上qwq)
————————————————————————————————————————————————————————
所以可以贪心的把每个元素分解为 k的n次幂:
分解方法除k取余(除k取得余数即是一个: k^n, 并标记是否用过)(与2进制的除2取余相似)————————————————————————————————————————————————————————
反思
- 在求一个数由k^n构成时,要想到模拟进制转换中的除k取余。
- k进制每一位下的1—代表10进制下k^n次幂
AC(咩哥代码)
#include <iostream>
#include <cstring>
#define mst(x,a) memset(x,a,sizeof(x))
#define For(i,x,y) for(int i=(x); i<=(y); i++)
using namespace std;
typedef long long ll;
ll vis[110];
const ll INF=1e16;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--)
{
mst(vis,0);
ll n,k;
cin>>n>>k;
int flag=1;
For(i,1,n)
{
ll a;
cin>>a;
for(int j=0; a&&j<=100; j++)
{
vis[j]+=a%k;
a/=k;
}
}
For(i,0,100)
{
if(vis[i]>1)
{
flag=0;
break;
}
}
if(flag)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}