Differential Sorting(贪心/构造)
时间:2022-11-09 20:30:01
题目
题目:给定一个数组,现在可以从数组中选择下标 1 < = x < y < z < = n 1<=x
想法:考虑到数组本身是非递减的。其次,我们注意到前面的元素只能用后面的元素来修改,我们发现, a n ? 1 , a n a_{n-1},a_n /span>an−1,an是不能被修改到的,因此,需要满足 a n − 1 < = a n a_{n-1}<=a_n an−1<=an。由于 a n a_n an决定了数组的最大值,如果 a n a_n an是负数,那么意味着,我们选择任意元素做为 z z z,都会使 a x a_x ax变大。所以,在数组本身不是非递减的情况,还需要满足 a n > = 0 a_n>=0 an>=0
在满足了 a n − 1 < = a n , a n > = 0 a_{n-1}<=a_n,a_n>=0 an−1<=an,an>=0这两个条件下,实际我们就可以构造了: a i = a n − 1 − a n , 1 < = i < = n − 2 a_i=a_{n-1}-a_n,1<=i<=n-2 ai=an−1−an,1<=i<=n−2
#include
using namespace std;
#define ll long long
const int maxn = 200010;
int n, a[maxn];
void solve() {
scanf("%d", &n);
int flag = 1;
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
if (i > 1 && a[i] < a[i-1]) {
flag = 0;
}
}
if (a[n-1] > a[n] || (a[n] < 0 && !flag)) {
printf("-1\n");
return;
}
if (flag) {
printf("0\n");
return;
}
printf("%d\n", n - 2);
for (int i = 1; i <= n - 2; ++i) {
printf("%d %d %d\n", i, n - 1, n);
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
}