D. Make Them Equal 思维构造

传送门

题意

您将得到一个由𝑛个正整数组成的数组array,从1到number编号。您最多可以执行3次以下操作:

选择三个整数𝑖,𝑗和𝑥(1≤𝑖,𝑗≤𝑛;0≤𝑥≤109);
分配𝑎𝑖:= 𝑎𝑖−𝑥⋅𝑖,𝑎𝑗:=𝑎𝑗𝑥⋅𝑖。
每次操作后,数组的所有元素都应为非负数。

您能找到不超过3个运算的序列,之后数组的所有元素都相等吗?

分析

很显然,处理完之后的合法数组每个数字就是数组和的平均数,题目最后还说明不要求操作次数最少,所以我们可以选择一个比较合适的过渡点

如果我们选择i为1的话,那么根据选择的x的不同,𝑥⋅𝑖可以包含所有整数,也就是说此时我们无论选择哪一个j,都可以保证有对应的x,使得操作完之后aj的值为平均值。
而题目要求每次操作完之后数组每一项都为非负数,所以我们可以提前预处理一下,把所有值都转移到a1上,再由a1进行分配

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <map>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define x first 
#define y second
#define _CRT_SECURE_NO_WARNINGS
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC option("arch=native","tune=native","no-zero-upper")
#pragma GCC target("avx2")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
struct xxx{
    int a,b,c;
};
const int INF = 0x3f3f3f3f;
const int N = 1e4 + 10;
int a[N];
vector<xxx> ans;
int n;

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        ans.clear();
        scanf("%d",&n);
        int sum = 0;
        for(int i = 1;i <= n;i++){
            scanf("%d",&a[i]);
            sum = sum + a[i];
        }
        if(sum % n != 0){
            puts("-1");
            continue;
        }
        int avg = sum / n;
        for(int i = 2;i <= n;i++){
            if(a[i] % i != 0){
                int t = a[i] % i;
                t = i - t;
                a[i] += t;
                ans.push_back({1,i,t});
            }
            ans.push_back({i,1,a[i] / i});
        }
        for(int i = 2;i <= n;i++) ans.push_back({1,i,avg});
        printf("%d\n",(int)ans.size());
        for(auto t:ans) printf("%d %d %d\n",t.a,t.b,t.c);
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值