CF1042C Array Product 分类讨论+贪心

考虑有无负数(负数的个数为奇视作“有”,否则为“无”)和有无零

无负数无零,全部合并即可

无负数有零,那么把零合并起来,删掉零

有负数无零,把最大的负数找出来,删掉,合并剩余的数

有负数有零,把零和最大的负数合并起来,删掉,合并剩余的数

注意如果只剩下一个数,不能删掉这唯一的一个数

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
    #define ri register int
    #define ll long long
    #define tpr template <typename ra>
    #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
    #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
    #define gc getchar
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
        while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
        return p * w;
    }
    int wr[50], rw;
    #define pc(iw) putchar(iw)
    tpr inline void write(ra o, char c = '
') {
        if(!o) pc('0');
        if(o < 0) o = -o, pc('-');
        while(o) wr[++ rw] = o % 10, o /= 10;
        while(rw) pc(wr[rw --] + '0');
        pc(c);
    }
    tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
    tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } 
    tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; }
    tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; }
}
using namespace std;
using namespace remoon;
#define sid 300050

int n, a[sid];

inline void Solve1() {
    rep(i, 2, n) printf("1 %d %d
", i, 1);
}

inline void Solve2() {
    
    int mip = -1e9 - 5, pos = 0;
    rep(i, 1, n) 
    if(a[i] < 0 && ckmax(mip, a[i])) pos = i;
    
    int fir = -1;
    rep(i, 1, n) if(pos != i) { fir = i; break; }
    if(fir == -1) return;
    
    printf("2 %d
", pos);
    if(pos != 1) {
        rep(i, 2, n) 
        if(pos != i) printf("%d %d %d
", 1, i, 1);
    }
    else rep(i, 3, n) printf("%d %d %d
", 1, i, 2);
    
}

inline void Solve3() {
    
    int lst = -1;
    rep(i, 1, n) if(a[i] == 0) {
        if(lst != -1) printf("%d %d %d
", 1, lst, i);
           lst = i;
    }
    
    int fir = -1;
    rep(i, 1, n) if(a[i] != 0) { fir = i; break; }
    if(fir == -1) return;
    
    printf("2 %d
", lst);
    rep(i, fir + 1, n) if(a[i] != 0)
    printf("%d %d %d
", 1, i, fir);

}

inline void Solve4() {
    
    int mip = -1e9 - 5, pos = 0;
    rep(i, 1, n) 
    if(a[i] < 0 && ckmax(mip, a[i])) pos = i;
    
    int lst = -1;
    rep(i, 1, n) if(a[i] == 0 || pos == i) {
        if(lst != -1)  printf("%d %d %d
", 1, lst, i);
        lst = i;
    }
    
    int fir = -1;
    rep(i, 1, n) if(a[i] != 0 && pos != i) 
    { fir = i; break; }
    if(fir == -1) return;
    
    printf("2 %d
", lst);
    rep(i, fir + 1, n) if(a[i] != 0 && pos != i)
    printf("%d %d %d
", 1, i, fir);

}

int main() {
    
    n = read();
    rep(i, 1, n) a[i] = read();
    
    int neg = 0, zero = 0;
    rep(i, 1, n) if(a[i] < 0) neg ^= 1;
    else if(a[i] == 0) zero |= 1;
    
    if(!zero && !neg) Solve1();
    else if(!zero && neg) Solve2();
    else if(zero && !neg) Solve3();
    else if(zero && neg) Solve4();
    
    return 0;
}
原文地址:https://www.cnblogs.com/reverymoon/p/9819257.html