luoguP7912 小熊的果篮 [CSP-J2 2021]

题目连接

  • 该题是CSP-J2 2021 T4 小熊的果篮

题目大意

给出一个绿球和红球的交叉分布序列,每轮取走所有同色区间最左边的一个,要求将每一轮的取数打印( $ n \leq 2 \times 10^5$)。
样例操作如下图:
luoguP7912 小熊的果篮 [CSP-J2 2021]_第1张图片


解法分析

作为普及组的压轴题,很容易让人浮想联翩,但是仔细分析,可以发现其实也不用高大上的算法或者数据结构(什么分块、排序树,先放一放)。
普遍的做法是队列或者链表完成, O ( n ) O(n) O(n) 即可解决问题。
以下是将每一块打包,然后压进队列,直接模拟扫描即可。


参考代码
//T4-小熊的果篮 
//CSP-J2 2021
#include 
using namespace std;
const int N=2e5+10;
struct node{ 
	int l,r,opt; 
};
int n,t;
queue<node> q,temp;
vector<int> ans[N];
bool vis[N];
int main(){
    cin>>n;
    int l=-1,r=-1,last=-1,x;
    for(int i=1;i<=n;i++){
        cin>>x;
        if(x!=last){				//判断颜色 
            if(last!=-1) q.push((node){l,r,last});
            l=i,r=i;
        }
        else r++;
        last=x;
    }
    q.push((node){l,r,last});
    while(!q.empty()){
        t++;
        int last=-1;
        int l,r; 
        while(!q.empty()){
            node now=q.front(); q.pop();
            if(now.opt!=last){
            	if(last!=-1&&l<=r) temp.push((node){l,r,last});
            	while(vis[now.l]) now.l++;
            	vis[now.l]=true;
				ans[t].push_back(now.l);
				now.l++;
				l=now.l;
				r=now.r;
            }
            else r=now.r;
            last=now.opt;
    	}
		if(l<=r) temp.push((node){l,r,last});	
        while(!temp.empty()){
            node add=temp.front();
            temp.pop(),q.push(add);
        }
    }
    for(int i=1;i<=t;i++){
        for(int j=0;j<ans[i].size();j++)
            printf("%d ",ans[i][j]);
        cout<<endl;
    }
    return 0;
}

你可能感兴趣的:(队列,题解,luogu,CSP-J/S,真题分析,luogu题解,CSP-J,2021)