CF1416B Make Them Equal--题解报告

题目

题目描述

You are given an array aa consisting of nn positive integers, numbered from 11 to nn . You can perform the following operation no more than 3n3n times:

  1. choose three integers ii , jj and xx ( 1 \le i, j \le n1≤i,j≤n ; 0 \le x \le 10^90≤x≤109 );
  2. assign a_i := a_i - x \cdot iai​:=ai​−x⋅i , a_j := a_j + x \cdot iaj​:=aj​+x⋅i .

After each operation, all elements of the array should be non-negative.

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

输入格式

The first line contains one integer tt ( 1 \le t \le 10^41≤t≤104 ) — the number of test cases. Then tt test cases follow.

The first line of each test case contains one integer nn ( 1 \le n \le 10^41≤n≤104 ) — the number of elements in the array. The second line contains nn integers a_1, a_2, \dots, a_na1​,a2​,…,an​ ( 1 \le a_i \le 10^51≤ai​≤105 ) — the elements of the array.

It is guaranteed that the sum of nn over all test cases does not exceed 10^4104 .

输出格式

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

  • if there is no suitable sequence of operations, print -1−1 ;
  • otherwise, print one integer kk ( 0 \le k \le 3n0≤k≤3n ) — the number of operations in the sequence. Then print kk lines, the mm -th of which should contain three integers ii , jj and xx ( 1 \le i, j \le n1≤i,j≤n ; 0 \le x \le 10^90≤x≤109 ) for the mm -th operation.

If there are multiple suitable sequences of operations, print any of them. Note that you don't have to minimize kk .

题意翻译

  • 给出一个序列 aa,求出一个长度不超过 3n3n 的操作序列,使序列 aa 中每个元素相等。

  • 定义一次操作为:选出 (i,j,x)(i,j,x) 三元组,满足 i,ji,j 为序列合法下标,xx 为 10^9109 以内非负整数,令 a_i:= a_i-x\cdot i,a_j:=a_j+x\cdot iai​:=ai​−x⋅i,aj​:=aj​+x⋅i。

  • 必须保证操作过程中的任意时刻序列 aa 中每个元素都非负。

  • 输出时先输出操作次数 kk,然后输出 kk 行操作序列。

  • 数据组数 t\le10^4t≤104,序列长度 n\le10^4n≤104,元素大小 1\le a_i\le10^51≤ai​≤105。

输入输出样例

输入 #1复制

3
4
2 16 4 18
6
1 2 3 4 5 6
5
11 19 1 1 3

输出 #1复制

2
4 1 2
2 3 3
-1
4
1 2 4
2 4 5
2 3 3
4 5 1

解题思路

首先要明白,如果sum/n除不尽,那一定没有结果,大概分为两种情况

1.a[i]能被i整除

2.a[i]不能被i整除

对于第一种情况可以直接把a[i]加到a[1]上

而对于第二种情况 则需要从a[1]“借”来一些数,让a[i]变为i的倍数,然后再当成第一种情况去做

总操作数为3*(n-1)

代码展示

#include<stdio.h>
#include<string.h>
int a[10010],sum=0;
int b[10010],t,n;
int main()
{
    int i;
    scanf("%d",&t);
    while(t--)
    {
        //初始化
        sum=0;
        memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
        scanf("%d",&n);

        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            sum=sum+a[i];
            b[i]=a[i]%i;//存a除以i的余数
        }
        if(sum%n!=0)//b你满足题中条件返回-1,结束本次循环
        {
            printf("-1\n");
            continue;
        }
        printf("%d\n",3*(n-1));//操作次数

        for(i=2; i<=n; i++)
        {
            printf("1 %d %d\n",i,(i-b[i])%i);
            if(b[i]!=0)//当a[i]不能被i整除时
            {
                //使其能被整除
                a[1]=a[1]-((i-b[i])%i);
                a[i]=a[i]+((i-b[i])%i);
            }
            printf("%d 1 %d\n",i,a[i]/i);
            a[1]=a[1]+a[i];
            a[i]=0;
        }
        for(i=2;i<=n;i++)
        {
            printf("1 %d %d\n",i,sum/n);
            a[1]=a[1]-sum/n;
            a[i]=sum/n;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值