[CF1523B] Lord of the Values

前言

有意思,但是不难。

题目

CF

题目大意:

\(t\) 组数据,每组数据给一个数组长度 \(n\),以及数组 \(a\)。要求通过以下两个操作使得 \(a\) 数组中的元素变为原来的相反数。

挑选下标 \(1\le i<j\le n.\)

  • \(a_i\) 加上 \(a_j\)
  • \(a_j\) 减去 \(a_i\)

保证 \(n\) 是偶数。操作数不能超过 \(5000\),操作过程中元素的绝对值不能超过 \(10^{18}\)

\(1\le t\le 10;2\le n\le 10^3;1\le a_i\le 10^9.\)

讲解

解法一(PPL、SY、ZXY、std...)

我们直接考虑两个数的时候怎么搞。

手玩后发现可以采用 \((2,1,1,2,1,1)\) 的操作。

类似的,还有 \((2,1,2,2,1,2),(1,2,1,1,2,1),(1,2,1,2,1,2),(2,1,2,1,2,1),(1,1,2,1,1,2)...\)

每相邻两个数都这么做,次数是 \(3n\)

浪费可耻。

解法二(XYX)

从后面开始,做操作 \(1\) ,可以使得每个数都变成后缀和,此时花费操作 \(n-1\) 次。

然后从后往前执行操作 \(2\) ,可以使得数组变成 \(Sum,-a_1,-a_2,...,-a_{n-1}\),此时花费操作 \(2n-2\) 次。

然后对 \(1\) 与 偶数位置的数字执行两次操作 \(1\),数组变为: \(\sum_{i=1}^{n}(-1)^ia_i,-a_1,-a_2,...,-a_{n-1}\)。此时花费操作 \(3n-2\) 次。

最后从前往后每相邻的两个数字都执行操作 \(2\) 与操作 \(1\),结束!

总花费 \(5n-4\) 次!

充分利用资源,不愧是标杆。

代码

解法一

/**
 *    author:  tourist
 *    created: 30.05.2021 17:40:11       
**/
#include <bits/stdc++.h>
 
using namespace std;
 
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int tt;
  cin >> tt;
  while (tt--) {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
      int foo;
      cin >> foo;
    }
    cout << 3 * n << '\n';
    for (int i = 1; i <= n; i += 2) {
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
      cout << "1 " << i << " " << i + 1 << '\n';
      cout << "2 " << i << " " << i + 1 << '\n';
    }
  }
  return 0;
}

解法二

#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 1005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
	LL f = 1,x = 0;char s = getchar();
	while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
	while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
	return f * x;
}
int n,m,i,j,s,o,k;
LL a[MAXN];
int main() {
	int T = read();
	while(T --) {
		n = read();
		for(int i = 1;i <= n;i ++) {
			a[i] = read();
		}
		printf("%d\n",4*(n-1)+n);
		for(int i = n;i > 1;i --)
			printf("1 %d %d\n",i-1,i);
		for(int i = n;i > 1;i --)
			printf("2 %d %d\n",i-1,i);
		for(int i = 2;i <= n;i += 2) {
			printf("1 %d %d\n",1,i);
			printf("1 %d %d\n",1,i);
		}
		for(int i = 1;i < n;i ++) {
			printf("2 %d %d\n",i,i+1);
			printf("1 %d %d\n",i,i+1);
		}
	}
	return 0;
}
posted @ 2021-05-31 22:39  皮皮刘  阅读(46)  评论(2编辑  收藏  举报