Title

CF1428D Bouncing Boomerangs 题解

解题思路

很简单的贪心。

观察发现以下性质:

  • ai=2 时,这一行一定只有两个目标,且第二个目标一定位于一个 aj=1 的格子内;
  • ai=3,那么当前列右边某一列发生转向的地方,aj0

那么这道题就基本已经做出来了。因为 ai=3 的格子转向格可以在任意非 0 列,而 ai=2 的转向格一定在 aj=1 列,那么我们考虑优先满足 ai=2 的列的需求。显然,不管怎么填,占用的行数是固定的,那么我们考虑第 i 列填在第 i 行,这样可以有效避免一些重复。接下来我们填 ai=3 的格子,贪心的从左往右找到第一个可以有转向格的列,然后直接填就可以了。最后把 ai=1 的补上就结束了。

注意,我们填的时候不需要考虑有没有填过,直接无脑填就可以了,最后再去重。

综上,本题步骤如下:

  • 从左往右找到所有 ai=1 的列,并按顺序放入一个队列中;
  • 从左往右枚举 ai=2 的列,并不断弹出队首直到队首列在当前列右侧,然后在队首列填入一个目标,并标记为已填;
  • 清空队列,从左往右枚举所有非 0 列,并放入队列中;
  • 从左往右枚举 ai=3 的列,找到第一个在当前列右侧的列,然后填入两个目标;
  • 枚举剩余的没有被填过的 ai=1 的列,向其中填入一个目标;
  • 排序去重输出答案。

注意事项

  • 在维护可填列的时候一定要使用队列来维护,贪心地从左往右填;
  • 注意纵坐标是从上往下递增的,而不是从下往上。

AC 代码

应该是比较短的代码了吧……

#include<bits/stdc++.h>
#define N 100005
#define p push_back
#define C continue
#define re register
#define pii std::pair<int,int>
std::vector<pii> A;
int n,a[N],vis[N];
signed main(){scanf("%d",&n);
    for(re int i=1;i<=n;++i)
        scanf("%d",&a[i]);
    std::queue<int> q;
    for(re int i=1;i<=n;++i)
        if(a[i]==1) q.push(i);
    for(re int i=1;i<=n;++i){
        if(a[i]!=2) C;
        while(q.size()&&q.front()<i) q.pop();
        if(q.empty()){puts("-1");return 0;}
        A.p({i,i});
        A.p({i,q.front()});
        vis[q.front()]=1;q.pop();
    }while(q.size()) q.pop();
    for(re int i=1;i<=n;++i){
        if(a[i]!=0&&!vis[i]) q.push(i);
    }for(re int i=1;i<=n;++i){
        if(a[i]!=3) C;
        while(q.size()&&q.front()<=i) q.pop();
        if(q.empty()){puts("-1");return 0;}
        A.p({i,i});A.p({i,q.front()});
        A.p({q.front(),q.front()});
        vis[q.front()]=1;q.pop();
    }for(re int i=1;i<=n;++i){
        if(a[i]!=1) C;
        if(vis[i]) C;A.p({i,i});
    }std::sort(A.begin(),A.end());
    int res=std::unique(A.begin(),A.end())-A.begin();
    printf("%d\n",res);
    for(re int i=0;i<res;++i){
        printf("%d ",A[i].first);
        printf("%d\n",A[i].second);
    }
}
posted @   UncleSam_Died  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示