版权声明:是自己手打的没错 https://blog.csdn.net/Mr_Treeeee/article/details/82874107
http://codeforces.com/contest/1042/problem/C
题意:
给你一个n个数的序列。两种操作。
1.选择序号i,j,去掉a[i],让a[j]=a[i]*a[j]。这个操作可以无限次。
2.选择序号i,去掉a[i]。
进过n-1次操作,只会剩下一个数,让这个数最大。
POINT:
如果负数是奇数个,那么绝对值最小的负数可以单独去掉,(如果有0,和0相乘后去掉)
如果是偶数个,那么全部乘起来就好,(如果有0,把0全部相乘后去掉)
注意全是0的情况。或者只有1个负数和全是0的情况。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <algorithm>
using namespace std;
#define LL long long
const int N = 2e5+55;
struct node
{
int val,i;
}x[N];
bool cmp(node a,node b)
{
return a.val<b.val;
}
int p[N];
int main()
{
int n;
scanf("%d",&n);
int num=0,flag=0;
for(int i=1;i<=n;i++){
scanf("%d",&x[i].val);
x[i].i=i;
if(x[i].val<0) num++;
else if(x[i].val==0) flag=1;
}
sort(x+1,x+1+n,cmp);
x[n+1].val=1;
if(num&1) flag=1;
if(flag){
int i;
if(num&1) i=num;
else i=num+1;
for(;;i++){
if(x[i+1].val==0){
p[x[i].i]=1;
printf("1 %d %d\n",x[i].i,x[i+1].i);
}else{
break;
}
}
if(i==n&&num<=1) return 0;
printf("2 %d\n",x[i].i);
p[x[i].i]=1;
}
int k[N],cnt=0;
for(int i=1;i<=n;i++){
if(!p[i]) k[++cnt]=i;
}
for(int i=1;i<cnt;i++)
printf("1 %d %d\n",k[i],k[i+1]);
}