C. Earning on Bets

题目要求
  • n个可能的结果,每个结构都有一个k_i

  • 你需要给每一个结果下注,结果如果获胜那你会获得下注的硬币数*k_i

  • 要求每个可能获胜的结果收到的硬币数量严格大于下注的硬币总数

思路
  • 对于本题我首先想到的思路就是二分答案,二分下注的硬币的总个数,我们依次枚举每一个k_i尽量小的去选择对于本个k_i我们下注多少硬币,如果找到一个满足的mid直接输出方案即可,没有找到的话那就不断的二分,在最后依旧没有找到就直接输出-1即可

代码
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define debug(x) cout << #x << " " << x << endl
const int N = 110;
int k[N];
int n;

bool check(int sum)
{
	vector<int> b(n + 1);
	int cnt = sum; // 下注的硬币总数
	for (int i = 1; i <= n; i++)
	{
		int num = sum / k[i] + 1; // 这次下注的最少数量
		if (cnt >= num) {
			cnt -= num;
			b[i] = num;
		}
		else {
			return false;
		}
	}
	
	// 如果合法的话直接输出
	for (int i = 1; i <= n; i++) {
		cout << b[i] << " ";
	}
	cout << endl;
	return true;
}

void solve()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		k[i] = 0;
	}
	for (int i = 1; i <= n; i++) {
		cin >> k[i];
	}
	// 二分答案
	int l = 0, r = 1e9;
	while (l < r)
	{
		int mid = l + r >> 1ll;
		if (check(mid))
		{
			r = mid;
			return;
		}
		else l = mid + 1;
	}
	cout << -1 << endl;
}
signed main()
{
	int T;
	cin >> T;
	while (T--)
	{
		solve();
	}
	return 0;
}

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值