构造题就是先分析性质,然后尽量简化过程,简单的进行构造。
这题分析下可知:
3后面必须要有1,或者2来与其构造。
2后面只能跟1.
所以就有了贪心构造:
从前往后,记录前面2,3的个数。1优先跟2配对,然后2,3与3配对。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define re register
#define ls (o<<1)
#define rs (o<<1|1)
//#define m (l+r)/2
#define pb push_back
typedef pair<int,int> pii;
const double PI= acos(-1.0);
const int M = 1e5+7;
/*
int head[M],cnt=1;
void init(int n){cnt=1;for(int i=0;i<=n;i++)head[i]=0;}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
*/
int a[M];
struct node{
int l,r;
}p[2*M];
queue<int>q[4];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int sz=0,lst=0,tp=0;
for(int i=1;i<=n;i++){
if(a[i]==0)continue;
if(q[2].size()&&a[i]==1){//前面有2未处理
lst=q[2].front();q[2].pop();
p[++sz]=node{lst,i};
q[a[i]].push(tp);
continue;
}
if(q[3].size()&&a[i]!=0){//前面有3未处理
lst=q[3].front();q[3].pop();
p[++sz]=node{lst,i};
p[++sz]=node{++tp,i};//当前障碍物的位置
q[a[i]].push(tp);
continue;
}
p[++sz]=node{++tp,i};
q[a[i]].push(tp);
}
// cout<<q[2].size()<<" "<<q[3].size()<<" "<<flag<<endl;
if(q[2].size()||q[3].size())cout<<"-1"<<endl;
else {
cout<<sz<<endl;
for(int i=1;i<=sz;i++){
if(p[i].l){
cout<<p[i].l<<" "<<p[i].r<<endl;
}
}
}
return 0;
}