题意:
给一个长度为 n 的数组 , 每次操作 可以选择一个 i , j , k ,使ai = ai − x ⋅ i , aj : = aj + x ⋅ i。求最多 3 * n 次操作内使每个数都相等的操作方法 ,操作过程每个数都不能变为负数。
思路:
- 首先我们可以发现 对于 a[i] 这个数,我们可以给数组中的其他任何一个数加上任意的值 ,前提是 a[i] 足够大。所以我们可以先把其他的数都加到 a[1] 上去 , 再把它分配给其他的数。
- 怎么把后面的值都分给 a[1] 呢 , 如果 a[i] % i == 0,可以直接分配 ,如果不等于 0 ,我们可以先用 a[i] 给它加上 一定的值使它能被 i 整除(这时 a[i] ,一定是够的 因为每个数至少为 1 ,你在给第i位补数时 ,前 i-1 位都已经转移到 a[1] 了)。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 4e6 + 7;
int T,n,a[maxn],sum,ave,ans;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
sum = ans = 0;
for(int i = 1; i <= n ; i ++){
scanf("%d",&a[i]);
sum += a[i];
if(a[i] % i) ans ++;
}
if(sum % n != 0){
printf ("-1\n");
continue;
}
ave = sum / n;
printf ("%d\n",2 * (n - 1) + ans);
for(int i = 2; i <= n; i ++){
if(a[i] % i == 0){
printf ("%d 1 %d\n",i , a[i] / i);
}
else{
printf ("1 %d %d\n",i,i - a[i] % i);
printf ("%d 1 %d\n",i,a[i] / i + 1);
}
}
for(int i = 2; i <= n; i ++){
printf ("1 %d %d\n",i,ave);
}
}
}
E题题解 :E. XOR Inverse