分析
因为每一个面额都是前面面额的整数倍,所以最终得到的答案减一的合成方案里每一张钞票的张数,一定没有达到后一种面额和该种面额的比值,否则就能用更少的张数来替换,例如现在有 \(1\) 和 \(10\),你 \(1\) 最多用 \(9\) 张,要不然只用一张 \(10\) 就替代了,所以从小到大考虑每一张钞票在答案中的张数,就是后一种面额除以该种面额的值减一,将这些求和,张数不足时便停止,若还有剩余,全加给最后一种。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline void read(int &res){
char c;
int f=1;
res=0;
c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=(res<<1)+(res<<3)+c-48,c=getchar();
res*=f;
}
int T;
int n,k;
int a[15];
int cf[15];
signed main()
{
read(T);
cf[0]=1;
for(int i=1;i<=10;i++)cf[i]=cf[i-1]*10;
while(T--){//代码中求的是答案减一,所以最后要加一
read(n);read(k);
for(int i=1;i<=n;i++)read(a[i]);
int ans=0,sum=0,cnt;
cnt=cf[a[2]-a[1]]-2;
if(cnt>k){
printf("%lld\n",k+1);
continue;
}
else ans=cnt,sum=cnt;
for(int i=2;i<n;i++){
cnt=cf[a[i+1]-a[i]]-1;
if(cnt+sum>k){
ans+=(k-sum)*cf[a[i]];
sum=k;
}
else {
ans+=cnt*cf[a[i]];
sum+=cnt;
}
}
if(sum<k)ans+=(k-sum)*cf[a[n]];
printf("%lld\n",ans+1);
}
return 0;
}