1606C - Banknotes

1606C - Banknotes


题目

n种不同类型的钞票,ai表示钞票是10^ai。

f(s)表示s由钞票组成的最小个数

例如:当ai=\left \{ 0 , 1, 2 \right \},f(59)>>9*1+5*10>>f(59)=9+5=14

给你 n个 ai 和 k,求f(s)>k的s


题解

f(s)>k代表f(s)=k+1;

我们要先用最小额度的钞票,一旦超过了第二个钞票的额度就不能在用第一种钞票了;

例:k=13  a= 0, 1 ,2;这时候10^0取9张,10^1取5张,答案为59;

    k= 777 a=0, 4; 这时候是10^0取778张因为没到第二个钞票的度;

因此,我们可以对ai提前进行处理,算出差值,而后去遍历一遍.


#include<bits/stdc++.h>
#define ms(a) memset(a,0,sizeof(a));
typedef long long ll;
using namespace std;
const int N = 1e5 + 5;
ll a[11], b[11];
ll get(ll a) {//取差额度
	ll ans = 1;
	for (int i = 0; i < a; i++) {
		ans *= 10;
	}
	return ans;
}
void solve() {
	ll n, k, ans = 0;
	cin >> n >> k;
	k++;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		if (i > 0) 
			b[i] = get(a[i] - a[i - 1]);
	}
	bool flag = 1;//标记是否k用完
	for (int i = 1; i < n; i++) {
		if (k >= b[i]) {
			ans += (b[i]-1) * get(a[i - 1]);
			k -= b[i] - 1;
		}
		else {
			ans += k * get(a[i - 1]);
			k -= k;
		}
		if (k == 0) 	flag = 0;
	}
	if (flag) ans += k * get(a[n - 1]);
	cout << ans << endl;
}
int main() {
	int t;
	cin >> t;
	while (t--) {
		solve();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值