地址:http://codeforces.com/contest/1042/problem/C
思维题:
细节好多,需要比较细心,因为0会影响结果,先用0把0消掉,然后只会有两种情况,一种是原先就没有0,第二种消成了一个0;没有0的话,负数的奇偶会影响结果最大值,所以如果有偶数个负数,不用管,有奇数个负数,用第二个操作去掉一个最大的负数;有一个0的话,如果有偶数个负数,用第二个操作去掉0,有奇数个负数,先用0把最大的负数消掉,然后再用第二个操作去掉产生的那个0;
细节:全是0的情况需要考虑,还有一个负数,其他全是0的情况,这两个需要特判一下
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int N = 2 * 1e5 + 5;
vector<int>ve;
bool vis[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis,false,sizeof(vis));
ve.clear();
int idmax = -1;
int MAX = -inf;
int ans = 0;
for(int i = 1;i <= n;++i)
{
int x;
scanf("%d",&x);
if(x == 0) ve.push_back(i);
if(x < 0) ans++;
if(x < 0 && MAX < x){
MAX = x;idmax = i;
}
}
//cout << idmax << " " << MAX << endl;
int len = ve.size();
for(int i = 0;i < len - 1;++i){
printf("1 %d %d\n",ve[i],ve[len - 1]);
vis[ve[i]] = true;
}
//没有负数或偶数个负数
if(idmax == -1 || !(ans & 1)){
//有0
if(len != 0){
if(len != n) {
printf("2 %d\n",ve[len - 1]);
vis[ve[len - 1]] = true;
}
}
}else{
//奇数个负数
if(len != 0){
int x = min(ve[len - 1],idmax);
int y = max(ve[len - 1],idmax);
vis[x] = true;
printf("1 %d %d\n",x,y);
if(len + 1 != n){
printf("2 %d\n",y);
vis[y] = true;
}
}else{
printf("2 %d\n",idmax);
vis[idmax] = true;
}
}
MAX = -1;
for(int i = 1;i <= n;++i)
{
if(!vis[i]) MAX = max(MAX,i);
}
for(int i = 1;i < MAX;++i)
{
if(!vis[i]) printf("1 %d %d\n",i,MAX);
}
}
return 0;
}