Description
给你一个长度为 \(n\) 的整数序列,你可以对其做两种操作:
- 选 \(i!=j\),将 \(a_j\) 替换为 \(a_i\cdot a_j\),删除 \(a_i\)。
- 选一个未被删除的 \(a_i\),将其删除。该操作在任意时刻均可执行,最多执行一次。
你需要操作 \(n-1\) 次,剩下一个数,使其最大。由于剩下的数可能会很大,你需要输出任意一种得到它的操作序列。
Solution
分类讨论
- 如果负数的个数是偶数
- 如果没有 \(0\),取绝对值处理即可
- 如果有 \(0\),将所有 \(0\) 乘在一起,消去,剩下的取绝对值处理即可
- 如果负数的个数是奇数
- 如果没有 \(0\),消去一个绝对值最小的负数,剩下的取绝对值处理即可
- 如果有 \(0\),先将所有 \(0\) 乘在一起,再将绝对值最小的负数乘到 \(0\) 上,消去这个 \(0\),剩下的取绝对值处理即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n,a[N];
signed main() {
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
vector <int> g0,e0,l0;
for(int i=1;i<=n;i++) {
if(a[i]>0) g0.push_back(i);
if(a[i]==0) e0.push_back(i);
if(a[i]<0) l0.push_back(i);
}
if(l0.size()%2==0) {
if(e0.size()==0) {
for(int i=1;i<n;i++) {
cout<<1<<" "<<i<<" "<<i+1<<endl;
}
}
else {
for(int i=1;i<e0.size();i++) {
cout<<1<<" "<<e0[i-1]<<" "<<e0[i]<<endl;
}
if(e0.size()<n) cout<<2<<" "<<*e0.rbegin()<<endl;
vector <int> tmp;
for(int i:l0) tmp.push_back(i);
for(int i:g0) tmp.push_back(i);
for(int i=1;i<tmp.size();i++) cout<<1<<" "<<tmp[i-1]<<" "<<tmp[i]<<endl;
}
}
else {
int mp=0;
for(int i=1;i<l0.size();i++) {
if(a[l0[i]]>a[l0[mp]]) mp=i;
}
mp=l0[mp];
if(e0.size()==0) {
cout<<2<<" "<<mp<<endl;
int fi=1;
if(mp==fi) ++fi;
for(int i=1;i<=n;i++) {
if(i!=fi && i!=mp) cout<<1<<" "<<i<<" "<<fi<<endl;
}
}
else {
for(int i=1;i<e0.size();i++) {
cout<<1<<" "<<e0[i-1]<<" "<<e0[i]<<endl;
}
cout<<1<<" "<<*e0.rbegin()<<" "<<mp<<endl;
if(e0.size()<n-1) cout<<2<<" "<<mp<<endl;
vector <int> tmp;
for(int i:l0) if(i!=mp) tmp.push_back(i);
for(int i:g0) tmp.push_back(i);
for(int i=1;i<tmp.size();i++) cout<<1<<" "<<tmp[i-1]<<" "<<tmp[i]<<endl;
}
}
}