D - Bouncing Boomerangs
分析
一个stack用于存只有一个的物品的行的物品位置,一个queue用于存有两个物品的行的左边物品位置
(其实这两个容器用stack还是queue无所谓,只是这样易于区分)
先安排最后一列:0不放,1在[n][n]的位置放
然后从n-1列往前逐列安排,策略:
a[i]=0,continue。
a[i]=1,往上升一行(即 去到一个全新的行),放置,同时把这个物品的信息压入stack。
a[i]=2,因为每行最多放两个物品,所以去找之前只有一个物品的行的物品,这个物品的行是tt,那么第i列放置位置为[tt][i]。把用过的物品从stack中弹出,同时把刚放置的物品位置压入queue。
a[i]=3,先找之前有两个物品的行的左边物品,让回旋镖第三次碰撞到这个物品上。因为这个物品的行已经有两个物品,不能再添加物品,所以可以看作“废弃的行”,那既然如此,为什么不让这个行发挥一下“余热”,去作为另一个回旋镖的第三次碰撞单位呢?所以,全新的一行为row,左边物品列是yy,那么放置的两个物品位置为[row][i]、[row][yy]。把用过的左边物品从queue中弹出,把[row][i]压入queue。
还是a[i]=3,如果找不到有两个物品的行,还可以找有一个物品的行的物品,让回旋镖第三次碰撞到这个物品上。作用和使用方法跟上一段的左边物品相同,但因为这一行不是“废弃的行”,所以不是首选。这个物品作为第三次碰撞的物品后,它的左边就不能再有物品,所以把物品信息从stack中弹出,把[row][i]压入queue。
在整个过程中,一旦发现stack或queue空了,导致没法安排当前元素,直接输出-1return。
用vector存答案,最后统一输出。
代码
#include<bits/stdc++.h>
#define ll long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int n,a[100005];
vector<pair<int, int> > v;
stack<pair<int, int> > s; //存只有一个的点行的点
queue<pair<int, int> > q; //存有两个点行的左边那个点
void solve(){
cin>>n;
rep(i,1,n){
cin>>a[i];
}
if(a[n]>1){
cout<<"-1\n"; return;
}
int temrow=0,flag;
if(a[n]==1){
v.push_back({n,n});
temrow=n;
s.push({n,n});
flag=1;
}
for(int i=n-1;i>=1;i--){
if(a[i]==0) continue;
if(a[i]==2){
flag=0;
if(s.empty()){
cout<<"-1\n";
return;
}
pair<int,int> tt=s.top();
s.pop();
v.push_back({tt.first, i});
q.push({tt.first, i});
}
if(a[i]==1){
flag=1;
if(temrow==0){
v.push_back({n,i});
temrow=n;
s.push({n,i});
continue;
}
if(temrow>1){
temrow--;
s.push({temrow,i});
v.push_back({temrow,i});
continue;
}
cout<<"-1\n"; return;
}
if(a[i]==3){
if(temrow>1){
temrow--;
v.push_back({temrow,i});
if(!q.empty()){
pair<int,int> tt=q.back();
q.pop();
v.push_back({temrow, tt.second});
q.push({temrow,i});
}
else{
if(s.empty()){
cout<<"-1\n";return;
}
pair<int,int> tt=s.top();
s.pop();
v.push_back({temrow, tt.second});
q.push({temrow,i});
}
continue;
}
cout<<"-1\n"; return;
}
}
if(v.empty()) {cout<<"0\n"; return;}
cout<<v.size()<<"\n";
rep(i,0,v.size()-1){
cout<<v[i].first<<" "<<v[i].second<<"\n";
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
//cin>>t;
while(t--){
solve();
}
return 0;
}