首先题目的意思是你要给n个结果都分配硬币,这些结果中只有一个会获胜,并给你你分配的硬币乘以k的硬币。
并且你分配的硬币之和必须要小于你赢得的硬币,注意这里赢得的硬币你必须要满足n种获胜的情况。
那么根据题干就可以得到最直接的一个式子,假如我们把我们分配出去的硬币的和设为
S
u
m
Sum
Sum,每个情况分配的硬币设为
a
i
a_i
ai。
那么就可以得到:
S
u
m
<
k
i
∗
a
i
Sum < k_i*a_i
Sum<ki∗ai
就可以推得:
s
u
m
k
i
<
a
i
\frac{sum}{k_i} < a_i
kisum<ai
所以我们每个硬币分配的数量都应该大于
s
u
m
k
i
\frac{sum}{k_i}
kisum。
所以我们必须满足
∑
i
=
1
n
s
u
m
k
i
<
s
u
m
\sum_{i = 1}^{n}\frac{sum}{k_i} < sum
i=1∑nkisum<sum
左右同除
s
u
m
sum
sum得到:
∑
i
=
1
n
1
k
i
<
1
\sum_{i = 1}^{n}\frac{1}{k_i} < 1
i=1∑nki1<1
这就是最终的式子了,但是题目要求分配的是正整数,不能分配分数个硬币,所以我们直接求出所有
k
i
k_i
ki的公倍数,让这些分数全部化为整数。
最后只需要验证一下,如果:
∑
i
=
1
n
1
k
i
l
c
m
(
k
1
,
k
2
,
…
k
n
)
<
l
c
m
(
k
1
,
k
2
,
…
k
n
)
\sum_{i = 1}^{n}\frac{1}{k_i}lcm(k_1,k_2,\dots k_n) < lcm(k_1,k_2,\dots k_n)
i=1∑nki1lcm(k1,k2,…kn)<lcm(k1,k2,…kn)
那么就说明这种分配方式是存在的可行的。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a,int b){
return b ? gcd(b,a%b) : a;
}
int lcm(int a,int b){
return a*b/gcd(a,b);
}
void solve(){
int n;cin >> n;
vector<int>k(n+1);
int now = 1;
for(int i = 1;i <= n;i++){
cin >> k[i];
now = lcm(now,k[i]);
}
vector<int>ans(n+1);
int sum = 0;
for(int i = 1;i <= n;i++){
ans[i] = now/k[i];
sum += ans[i];
}
if(sum < now){
for(int i = 1;i <= n;i++)cout << ans[i] << ' ';
cout << endl;
}else{
cout << -1 << endl;
}
}
int main(){
int T;cin >> T;
while(T--){
solve();
}
return 0;
}