Description
给你一个长度为 (n) 的整数序列,你可以对其做两种操作:
- 选 (i!=j),将 (a_j) 替换为 (a_icdot 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;
}
}
}