6.6 CodeForces Round 951 Div2 C

题面

amount of coins. In the event that the i-th outcome turns out to be winning, you will receive back the amount of coins equal to your bet on that outcome, multiplied by ki. Note that exactly one of the n

outcomes will be winning.

Your task is to determine how to distribute the coins in such a way that you will come out ahead in the event of any winning outcome. More formally, the total amount of coins you bet on all outcomes must be strictly less than the number of coins received back for each possible winning outcome.

DeepL 翻译

有人提议让您玩一个游戏。在这个游戏中,有 n

种可能的结果,对于每一种结果,您都必须下注一定整数的硬币。如果 i ()的结果是赢,您将获得与该结果投注额相等的硬币,再乘以 ki 。请注意, n

个结果中只有**个结果是赢的。

你的任务是决定如何分配硬币,以便在出现任何*中奖结果时都能获胜。更正式地说,你在所有结果上投注的硬币总数必须严格地小于每个可能获胜的结果所得到的硬币数量。

输入

Each test consists of multiple test cases. The first line contains a single integer t (1≤t≤104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains a single integer n(1≤n≤50) — the number of outcomes.

The second line of each test case contains n integers k1,k2,…,kn (2≤ki≤20) — the multiplier for the amount of coins if the i -th outcome turns out to be winning.

It is guaranteed that the sum of n over all test cases does not exceed 2e5;

.

输出

For each test case, output −1 if there is no way to distribute the coins as required. Otherwise, output n integers x1,x2,…,xn (1≤xi≤109

) — your bets on the outcomes.

It can be shown that if a solution exists, there is always a solution that satisfies these constraints.

If there are multiple suitable solutions, output any of them.

Solution

一,假定下注量为 S,为了每个结果的收获都能大于下注,很容易想到,为了 k[i]* x[i]>S,每种情况至少要下注 S/k[i]向上取整,对各种情况的需要进行累加,与假定的下注量进行对比,即可知道是否存在一种情况能使得每种结果都能获得收益

二,由一,接下来需要考虑的就是,如何假定这么一个可能存在的S了,为了避免出现整形存分数的精度取舍问题,这里使用的是 LCM,最小公倍数,因为 x[i] <=1e9 ,所以使即使是最坏情况, x[i]*x[j]只要用 long long 即可存储,同时因子数量一般极限不超过1e2,且LCM特性,long long 存储 LCM完全可行,需要注意的就只有LCM的求法了

这里使用的是 LCM( a[0],a[1]... a[n[) == LCM( a[2], LCM (a[0],a[1]) ,a[2] ...)的分解特性
	ll lc = 1;
	for (int right = 1; right < n; right++) {
		ll g=lcm(nums[right],nums[right-1]);
	    lc=lcm(lc,g);
	}

代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <numeric>
#include <cmath>
using namespace std;

int t = 0;

typedef long long   ll;
#define endl '\n'

ll gcd(ll a, ll b) {
	return a % b == 0 ? b : gcd(b, a % b);
}

int lcm(ll a, ll b) {
	return  a * b / gcd(a, b);
}


void solve() {

	int n;
	cin >> n;
	vector<ll > nums(n);

	ll sum = 0, m = 0;

	for (int i = 0; i < n; i++) {
		cin >> nums[i];
		if (nums[i] >= nums[m])
			m = i;
	}

    if(n==1){
        cout << (nums[0]>1 ?1:-1)<<endl;
        return;
    }



	// 求 LCM 
	ll lc = 1;
	for (int right = 1; right < n; right++) {
		ll g=lcm(nums[right],nums[right-1]);
	    lc=lcm(lc,g);
	}
	

	vector < ll>  a(n);
	for (int i = 0; i < n; i++) {
		a[i] = lc / nums[i];
		sum += a[i];
	}

	if (sum >= lc) {
		cout << -1 << endl;
		return;
	}


	for (int i = 0; i < n; i++)
		if (a[i] * nums[i] < sum || a[i]>1e9) {
			cout << -1 << endl;
			return;
		}

	for (int i : a)
		cout << i << " ";

	cout << endl;

}


int main() {

	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cin >> t;
	while (t--) {
		solve();
	}
}

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值