栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

蓝桥杯 双向排序【省赛】【研究生组】

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

蓝桥杯 双向排序【省赛】【研究生组】

 

可以结合AcWing的视频讲解深入理解: AcWing 3419. 双向排序(蓝桥杯C++ AB组辅导课) - AcWing

C++解答:

#include
#include
#include

using namespace std;

#define N 100010

pair stack[N]; //存储可以执行的操作的栈

int ans[N];  // 存储答案 

int main()
{
	int n, m;
	cin>>n>>m;
	int a, b, top = 0;  //top栈顶 
	//需要明白的是,栈内最终存储的是前缀和后缀的交替操作,并且交集部分是递减的 
	while(m --)
	{
		cin>>a>>b;
		if(a == 0)  //前缀降序
		{
			// 将所有相连且相同的操作整合为一个,省略不必要操作
            // 同为前缀,操作坐标小的可以被操作坐标大的代替(内部排序可以被整体排序代替)
            // 同为后缀,操作坐标大的可以被操作左边小的代替
			while(top!=0 && stack[top].first==0)
			{
				b = max(b, stack[top].second);  //保留操作坐标大的 
				top--; //出栈 
			}
			// 若后缀操作前面的前缀操作比当前的前缀操作数小,可以将前、后缀操作均省略(内部排序可以被整体排序代替)
			while(top>=2 && stack[top-1].second<=b)
			{
				top = top - 2;  //出两次栈,相当于同时省略前面的一次前缀和一次后缀操作 
			}
			stack[++top] = make_pair(a, b); //入栈 
		}
		else  //后缀升序 
		{
			if(top != 0)  //第一步有意义的操作肯定是前缀降序(如果第一步是后缀升序,原始数列本来就是升序的) 
			{
				//后缀的情况同理 
				while(top!=0 && stack[top].first==1)
				{
					b = min(b, stack[top].second);
					top--;
				}
				while(top>=2 && stack[top-1].second>=b)
				{
					top = top - 2;
				}
				stack[++top] = make_pair(a, b);
			}
		}
	}
	int k = n;  //用于计数填空ans 
	int l=1, r=n;  //创建左右端点,记录已经排列的坐标
	for(int i=1; i<=top; i++)  //将栈从栈底到栈顶遍历一遍,把栈当作队列使用 
	{
		if(stack[i].first == 0)
		{
			// 若本操作为前缀,操作坐标之后的数就不会再被修改,即可确定进入答案数组
            // 后缀为升序,从后往前即为  k -- 操作
			while(r>stack[i].second && l<=r)
			{
				ans[r--] = k--;
			}
		}
		else
		{
			// 若本操作为后缀,操作坐标之前的数就不会再被修改,即可确定进入答案数组
            // 前缀为逆降,从前往后即为  k -- 操作
            while(l 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/767598.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号