Gushing over Pr|

BigSmall_En

园龄:3年2个月粉丝:3关注:5

2022-10-24 22:10阅读: 25评论: 0推荐: 0

CF1428D Bouncing Boomerangs 题解

CF1428D Bouncing Boomerangs

\(n\times n\) 的网格上,有若干目标。从最低下扔回旋镖,碰到目标会右转。每行、每列不超过两个目标。现在已知从每一列认出会撞到 \(a_i\) 个障碍(\(a_i\leq 3\)),请求出一种合法方案。

考虑从左到右的每一列加入一个点之后,如何匹配更左侧的尚未匹配完全的回旋镖(即左侧有些回旋镖需要经过多个点)。我们让每次加入的点的行数依次递增,所以匹配的时候匹配最先加入的,即对两种待匹配的点用队列存下来。

分类讨论

  • \(a_i=1\)。如果先前有 \(a_i=2\) 的回旋镖尚未匹配完全,则该列的点的行数同那个 \(a_i=2\) 的回旋镖的行数;如果先前有 \(a_i=3\) 的回旋镖尚未匹配完全,则该列的第一个点的行数同那个 \(a_i=3\) 的回旋镖的行数,同时再新建一个点,行数为目前最大的行数 \(+1\)。(特别注意这题行数编号越小越在上面)。
  • \(a_i=2\)。因为每行只能有两个点,所以不能接一个 \(a_i=2\) 的回旋镖之后。于是可以考虑匹配 \(a_i=3\) 的回旋镖,匹配方式与 \(a_i=1\) 的情况相同。同时这个点要加入 \(a_i=2\) 的回旋镖的队列中
  • \(a_i=3\)。可以像 \(a_i=2\) 的情况一样匹配一个 \(a_i=3\) 的回旋镖。同时要加入 \(a_i=3\) 的队列中。
  • \(a_i=0\)。不用管。

具体实现见代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>

using namespace std;
typedef long long ll;
typedef pair<int,int>ttfa;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=1000006;
int n,a[N],poi,hei[N];
queue<int>q2,q3;
ttfa ans[N*2];int cnt;

inline void insert1(int loc){
	if(q2.size()){
		int pre=q2.front();q2.pop();
		hei[loc]=hei[pre];
		ans[++cnt]={loc,hei[loc]};
	}else if(q3.size()){
		int pre=q3.front();q3.pop();
		ans[++cnt]={loc,hei[pre]};
		ans[++cnt]={loc,hei[loc]=++poi};
	}else{
		hei[loc]=++poi;
		ans[++cnt]={loc,hei[loc]};
	}
}
inline void insert2(int loc){
	if(q3.size()){//每行只能有两个元素,所以不能接一个2
		int pre=q3.front();q3.pop();
		ans[++cnt]={loc,hei[pre]};
		ans[++cnt]={loc,hei[loc]=++poi};
	}else{
		ans[++cnt]={loc,hei[loc]=++poi};

	}
	q2.push(loc);
}
inline void insert3(int loc){
	if(q3.size()){
		int pre=q3.front();q3.pop();
		ans[++cnt]={loc,hei[pre]};
		ans[++cnt]={loc,hei[loc]=++poi};
	}else{
		ans[++cnt]={loc,hei[loc]=++poi};
	}
	q3.push(loc);
}
int main(){
	n=read();
	for(int i=1;i<=n;++i){
		a[i]=read();
		if(a[i]==0)continue;
		if(a[i]==1)insert1(i);
		if(a[i]==2)insert2(i);
		if(a[i]==3)insert3(i);
	}
	if(q2.size()||q3.size())puts("-1");
	else{
		printf("%d\n",cnt);
		for(int i=1;i<=cnt;++i)
			printf("%d %d\n",ans[i].second,ans[i].first);
	}
	return 0;
}
//orzzzz

本文作者:BigSmall_En

本文链接:https://www.cnblogs.com/BigSmall-En/p/16823223.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   BigSmall_En  阅读(25)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起