D. Make Them Equal 构造

D. Make Them Equal 构造

构造题真的就是想到好写,不过基本想不到,本题想到了就稍微记录一下(题意和思路都在代码块内)
D. Make Them Equal
在这里插入图片描述

//https://codeforces.com/contest/1417/problem/D
//长度为n的序列,在操作次数不超过3*n的情况下,使得所有元素值相等,可以则输出方案,否则输出-1
//同时每次操作后不能有元素为非负数
//单次操作:选择一个三元组{i,j,x} a[i]=a[i]-x*i  a[j]=a[j]+x*i
//显然,如果sum%n!=0,一定不可以
//构造方案:
//第一步:从2开始for一遍,每次将其所有数都转移给1。
//①若a[pos]%pos==0,可以直接转给1 ,操作:{pos,1,a[pos]/pos}
//②若a[pos]%pos!=0,那么1<=a[pos]%pos<pos,要是的a[pos]%pos==0,可以(a[pos]+x)%pos,即给a[pos]加上一个数x
// 数据保证了初始1<=a[i]<=1e5,则前pos-1个数的总和>=pos-1,可以满足任意a[pos]所需的任意x。
// 即先位置1给位置pos数x,在全部转给1  操作:{1,pos,(i-a[pos]%pos)},{pos,1,(a[pos]+(i-a[pos]%pos))/i}
//第二步:此时全部的数都在位置1,再从2开始for一遍,每次从位置1转给位置i数sum/n, 操作:{1,i,sum/n};

//第一步操作次数最多2*(n-1),第二步操作次数n-1,总操作次数最多3*(n-1)<3*n
          
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,a[N];
struct node{int st,ed,x;};
vector<node>ans;
vector<pair<int,int> >hh;

void solve(){
    ans.clear(),hh.clear();
    int sum=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),sum+=a[i];
    if(sum%n!=0){puts("-1");return;}
    int ned=sum/n;
    
    for(int i=2;i<=n;i++){
        int yu=a[i]%i;
        if(yu==0) ans.push_back({i,1,a[i]/i});
        else{
            ans.push_back({1,i,i-yu});
            ans.push_back({i,1,(a[i]+i-yu)/i});
        }
    }
    for(int i=2;i<=n;i++) ans.push_back({1,i,ned});
    int len=ans.size();
    printf("%d\n",len);
    for(int i=0;i<len;i++) printf("%d %d %d\n",ans[i].st,ans[i].ed,ans[i].x);
}

int main(){
    int t;scanf("%d",&t);
    while(t--) solve();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值