Codeforces Round #673 (Div. 2) D. Make Them Equal

D. Make Them Equal
Description

You are given an array a consisting of n positive integers, numbered from 1 to n. You can perform the following operation no more than 3n times:

  • choose three integers i, j and x ( 1 ≤ i , j ≤ n ; 0 ≤ x ≤ 1 0 9 ) 1≤i,j≤n; 0≤x≤10^9) 1i,jn;0x109);
  • assign a i : = a i − x ⋅ i , a j : = a j + x ⋅ i a_i:=a_i−x⋅i, a_j:=a_j+x⋅i ai:=aixi,aj:=aj+xi.
    After each operation, all elements of the array should be non-negative.

Can you find a sequence of no more than 3n operations after which all elements of the array are equal?

Input

The first line contains one integer t (1≤t≤104) — the number of test cases. Then t test cases follow.

The first line of each test case contains one integer n (1≤n≤104) — the number of elements in the array. The second line contains n integers a1,a2,…,an (1≤ai≤105) — the elements of the array.

It is guaranteed that the sum of n over all test cases does not exceed 104.

Output

For each test case print the answer to it as follows:

if there is no suitable sequence of operations, print −1;
otherwise, print one integer k (0≤k≤3n) — the number of operations in the sequence. Then print k lines, the m-th of which should contain three integers i, j and x (1≤i,j≤n; 0≤x≤109) for the m-th operation.
If there are multiple suitable sequences of operations, print any of them. Note that you don’t have to minimize k.

Example
input
3
4
2 16 4 18
6
1 2 3 4 5 6
5
11 19 1 1 3
output
2
4 1 2
2 3 3
-1
4
1 2 4
2 4 5
2 3 3
4 5 1

题意: 给出一个数组,从数组中选出第i个和第j个按照以下规则进行运算:

  • a i = a i − i ∗ x a j = a j + i ∗ x a_i = a_i - i*x \quad a_j = a_j+i*x ai=aiixaj=aj+ix

i 、 j i、j ij是数组下标, x x x是任意的一个数。求经过多少次这样的变换可以使得数组a中的所有元素都相等。(操作步数在3n次操作以内)

题解: 将ai变成0,a1变成所有元素的和,最后在平分给所有元素。

c++ AC 代码

#include <bits/stdc++.h>
using namespace std;

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, sum = 0;
		scanf("%d", &n);
		vector<int> a(n + 1);
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &a[i]);
			sum += a[i];
		}
		if (sum % n)
		{
			puts("-1");
			continue;
		}
		printf("%d\n", 3 * (n - 1));
		for (int i = 2; i <= n; i++)
		{
			printf("1 %d %d\n", i, (i - (a[i] % i)) % i);	// 先将a[i]加上除以i之后的余数
			printf("%d 1 %d\n", i, (a[i] + i - 1) / i);	// 再将a[i]减去它除以i之后的数再乘以i,即减去它自己
		}
		for (int i = 2; i <= n; i++)
			printf("1 %d %d\n", i, sum / n);	// 将a[1]平分给其他元素
	}
	// system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值