1. 程式人生 > >Codeforces 1042C (貪心+模擬)

Codeforces 1042C (貪心+模擬)

題面

傳送門

分析

思路簡單,但程式碼較複雜的貪心 分類討論:

  • 有0
    • 負數有奇數個:將絕對值最小(實際最大)的負數和0全部乘到一起,最後刪掉0
    • 負數有偶數個:將0全部乘到一起,最後刪掉0
  • 沒有0
    • 負數有奇數個:將絕對值最小(實際最大)的負數刪掉
    • 負數有偶數個:不刪 最後把剩下的數依次乘在一起即可

程式碼


#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define maxn 200005
#define INF 0x7fffffff
using namespace
std; int n; long long a[maxn]; struct oper { int type; int i; int j; oper() { } oper(int x,int y,int z) { type=x; i=y; j=z; } void print() { if(type==1) { printf("%d %d %d\n",type,i,j); } else { printf("%d %d\n",type,i); } } }; vector<int>zeros; vector<oper>res;
int main() { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%I64d",&a[i]); } int cntneg=0,cnt0=0; long long maxneg=-INF; int del=0; for(int i=1; i<=n; i++) { if(a[i]==0) { zeros.push_back(i);//記錄0的位置 cnt0++; } else if(a[i]<0) { cntneg++; if(a[i]>maxneg) { maxneg=
a[i]; del=i;//記錄最大的負數的位置 } } } for(int i=0;i<cnt0-1;i++){ res.push_back(oper(1,zeros[i],zeros[i+1]));//將0全部挪到一起 } if(cntneg%2==1){//分類討論 if(cnt0!=0) res.push_back(oper(1,del,zeros[cnt0-1])),res.push_back(oper(2,zeros[cnt0-1],0)); else res.push_back(oper(2,del,0)); }else if(cnt0!=0) res.push_back(oper(2,zeros[cnt0-1],0)); int last=0; for(int i=1; i<=n; i++) { if(a[i]!=0) { if(cntneg%2==1&&i==del) continue; else if(last==0) { last=i; continue; } else res.push_back(oper(1,last,i)); last=i; } } for(int i=0; i<n-1; i++) { res[i].print(); } }