题目要求
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;
}