题目大意
给你一个长度为 n n n的整数序列,你可以对其做两种操作:
1 1 1、选 0 < i , j ≤ n , i ̸ = j 0< i,j\le n,i\not= j 0<i,j≤n,i̸=j,将 a j a_j aj替换为 a i ⋅ a j a_i\cdot a_j ai⋅aj,删除 a i a_i ai。
2 2 2、选一个未被删除的 a i a_i ai,将其删除。该操作在任意时刻均可执行,最多执行一次。
你需要操作 n − 1 n-1 n−1次,剩下一个数,使其最大。由于剩下的数可能会很大,你需要输出得到它的操作序列。
输出任意能得到最大数的操作序列均可。
solution
考虑贪心选取,由于是各个数相乘,考虑有奇数个负数,则负数一定要删去一个。
再考虑 0 0 0的情况,可以把所有的 0 0 0都乘到一起,如果多一个负数,就把负数也乘进来,最终得到答案。
注意只有 n − 1 n-1 n−1个操作,对于全零情况,要留一个,不能全删去。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <bitset>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
struct FastIO
{
inline FastIO& operator >> (int& x) {
x = 0; char f = 0, ch = getchar();
while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
return x = (f ? -x : x), *this;
}
inline FastIO& operator >> (long long& x) {
x = 0; char f = 0, ch = getchar();
while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while(ch <= '9' && ch >= '0') x = x * 10 + ch - 48, ch = getchar();
return x = (f ? -x : x), *this;
}
inline FastIO& operator >> (double& x)
{
x = 0; char f = 0, ch = getchar();
double d = 0.1;
while(ch > '9' || ch < '0') f |= (ch == '-'), ch = getchar();
while(ch <= '9' && ch >= '0') x=x * 10 + ch - 48, ch = getchar();
if(ch == '.')
{
ch = getchar();
while(ch <= '9' && ch >= '0') x += d * (ch ^ 48), d *= 0.1, ch = getchar();
}
return x = (f ? -x : x), *this;
}
}rin;
const int N = 5e5 + 50;
int f[N];
int li, fu;
int vis[N];
vector <int> pos;
int main() {
int n, cnt = 0;
rin >> n;
for(int i = 1 ; i <= n ; ++ i) {
rin >> f[i];
if(f[i] == 0) ++ li;
if(f[i] < 0) ++ fu;
}
int del = 0;
if(fu & 1) {
int maxn = -(1 << 30);
for(int i = 1 ; i <= n ; ++ i) {
if(f[i] < 0) {
if(maxn < f[i]) {
maxn = f[i];
del = i;
}
}
}
vis[del] = 1;
}
if(li) {
for(int i = 1 ; i <= n ; ++ i) {
if(f[i] == 0) {
vis[i] = 1;
pos.push_back(i);
}
}
if(del) printf("1 %d %d\n", del, pos[0]), ++ cnt;
for(int i = 1 ; i < pos.size() ; ++ i) printf("1 %d %d\n", pos[i - 1], pos[i]), ++ cnt;
del = pos[pos.size() - 1];
}
int las = 0;
for(int i = 1 ; i <= n ; ++ i) {
if(vis[i]) continue;
las = i;
break;
}
for(int i = las + 1 ; i <= n ; ++ i) {
if(vis[i]) continue;
printf("1 %d %d\n", las, i);
++ cnt;
las = i;
}
if(del != 0 && cnt < n - 1) printf("2 %d\n", del);
return 0;
}