蓝桥杯第十三届决赛真题-左移右移

这篇具有很好参考价值的文章主要介绍了蓝桥杯第十三届决赛真题-左移右移。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目链接

问题描述

小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3, …N 。
之后小蓝对这个数组进行了 M 次操作, 每次操作可能是以下 2 种之一:
左移 x, 即把 x 移动到最左边。
右移 x, 即把 x 移动到最右边。
请你回答经过 M 次操作之后, 数组从左到右每个数是多少?

输入格式

第一行包含 2 个整数, N 和 M。
以下 M 行每行一个操作, 其中 “L x "表示左移 x, "R x "表示右移 x 。

输出格式

输出 N 个数, 代表操作后的数组。

样例输入

5 3
L 3
L 2
R 1

样例输出

2 3 4 5 1

样例说明
样例中的数组变化如下:

[1,2,3,4,5]→[3,1,2,4,5]→[2,3,1,4,5]→[2,3,4,5,1]
评测用例规模与约定
对于50% 的评测用例, 1 ≤ N,M ≤ 10000.
对于 100% 的评测用例,1 ≤ N,M ≤ 200000,1 ≤ x ≤ N.

运行限制

最大运行时间:3s
最大运行内存: 512M

一、思路分析

首先最容易想的的办法就是创建一个数组,把1 - N的数字放进去,然后按照后面输入的字符(LR)和数字来操作:先找到数字,再挪动到头部或者尾部。
但是我们发现这种算法的时间复杂度是O(N ^ 2),而且这道题也会时间超时。那么下面就引入用数组模拟双链表的方法:

二、数组模拟双链表❗️❗️

在前面的文章我们讲过双向链表,用链表进行插入就可以不用挪动数据,但是我们发现查找数据还得遍历,那样又会变成O(N ^ 2),所以我们可以采用数组模拟。
先用一张图来演示:
假设我们要模拟这样一个链表:
蓝桥杯第十三届决赛真题-左移右移
现在我们用数组模拟就需要三个数组:一个是存放数值的数组,一个是记录节点左边位置的数组,一个是记录节点右边位置的数组。

	int e[MAX];// 节点数据
	int l[MAX];// 记录当前节点的左节点
	int r[MAX];// 记录当前节点的右节点
	int index;// 记录e下一个要插入的位置

我们让e的第0个位置代替head,第一个位置代替tail。
那么真实的结构是这样的:
蓝桥杯第十三届决赛真题-左移右移
红的的数字就是我们首先要初始化的地方,也就是让我们找到头和尾。

而且index也需要初始化成2,因为0 和 1 的位置已经被占了,只能从下标2的位置开始插入。
构造函数:

	mylist()
		: index(2)
	{
		// 0位置表示头,1位置表示尾
		l[1] = 0;
		r[0] = 1;
	}

在pos位置的右边插入数字:
蓝桥杯第十三届决赛真题-左移右移
绿线表示链接的顺序,注意3和4的顺序不能变

	// 在pos的右边插入
	void insert(int pos, int x)
	{
		// 先插入到e中
		e[index] = x;
		// 四根线
		l[index] = pos;
		r[index] = r[pos];
		l[r[pos]] = index;
		r[pos] = index;
		index++;
	}

针对这道题目为了方便我们直接加一个尾插的成员函数:

	void push_back(int x)
	{
		e[index] = x;
		l[index] = l[1];
		r[index] = 1;
		r[l[1]] = index;
		l[1] = index;
		index++;
	}

删除节点:
首先要知道并不是真的把当前位置清理,而是让pos位置的左右位置的 l 和 r 改变。我们就可以发现删除并不影响e数组中的数据相对位置

	// 并不是真的删除
	void pop(int pos)
	{
		// 左右互连
		r[l[pos]] = r[pos];
		l[r[pos]] = l[pos];
	}

从左向右打印:
怎么找到head?

r[0]

	void print()
	{
		for (int i = r[0]; i != 1; i = r[i])
		{
			cout << e[i] << " ";
		}
		cout << endl;
	}

这道题我们还需要挪动数据,所以再写个成员函数:

	// 将pos位置的数字挪到最左/右边
	void move(char ch, int pos)
	{
		// 先删除pos位置(l和r)
		pop(pos);
		// 设置pos位置的l和r
		if (ch == 'L')
		{
			l[pos] = 0;
			r[pos] = r[0];
			l[r[0]] = pos;
			r[0] = pos;
		}
		else
		{
			l[pos] = l[1];
			r[pos] = 1;
			r[l[1]] = pos;
			l[1] = pos;
		}
	}

通过这里我们就发现这道题用数组模拟链表的好处了:
比方说我们要找3,那么下标就是4,而且就算把3移动了,改变的也是 l 和 r 数组,不会影响e,再找下一个数字也可以这么找。

整个类的代码:文章来源地址https://www.toymoban.com/news/detail-407680.html

class mylist
{
public:
	mylist()
		: index(2)
	{
		// 0位置表示头,1位置表示尾
		l[1] = 0;
		r[0] = 1;
	}

	// 在pos的右边插入
	void insert(int pos, int x)
	{
		// 先插入到e中
		e[index] = x;
		// 四根线
		l[index] = pos;
		r[index] = r[pos];
		l[r[pos]] = index;
		r[pos] = index;
		index++;
	}

	void push_back(int x)
	{
		e[index] = x;
		l[index] = l[1];
		r[index] = 1;
		r[l[1]] = index;
		l[1] = index;
		index++;
	}

	// 并不是真的删除
	void pop(int pos)
	{
		// 左右互连
		r[l[pos]] = r[pos];
		l[r[pos]] = l[pos];
	}

	void print()
	{
		for (int i = r[0]; i != 1; i = r[i])
		{
			cout << e[i] << " ";
		}
		cout << endl;
	}

	// 将pos位置的数字挪到最左/右边
	void move(char ch, int pos)
	{
		// 先删除pos位置(l和r)
		pop(pos);
		// 设置pos位置的l和r
		if (ch == 'L')
		{
			l[pos] = 0;
			r[pos] = r[0];
			l[r[0]] = pos;
			r[0] = pos;
		}
		else
		{
			l[pos] = l[1];
			r[pos] = 1;
			r[l[1]] = pos;
			l[1] = pos;
		}
	}

private:
	int e[MAX];// 节点数据
	int l[MAX];// 记录当前节点的左节点
	int r[MAX];// 记录当前节点的右节点
	int index;// 记录e下一个要插入的位置
};

三、代码展示

#include <iostream>
using namespace std;

const int MAX = 200002;

class mylist
{
public:
	mylist()
		: index(2)
	{
		// 0位置表示头,1位置表示尾
		l[1] = 0;
		r[0] = 1;
	}

	// 在pos的右边插入
	void insert(int pos, int x)
	{
		// 先插入到e中
		e[index] = x;
		// 四根线
		l[index] = pos;
		r[index] = r[pos];
		l[r[pos]] = index;
		r[pos] = index;
		index++;
	}

	void push_back(int x)
	{
		e[index] = x;
		l[index] = l[1];
		r[index] = 1;
		r[l[1]] = index;
		l[1] = index;
		index++;
	}

	// 并不是真的删除
	void pop(int pos)
	{
		// 左右互连
		r[l[pos]] = r[pos];
		l[r[pos]] = l[pos];
	}

	void print()
	{
		for (int i = r[0]; i != 1; i = r[i])
		{
			cout << e[i] << " ";
		}
		cout << endl;
	}

	// 将pos位置的数字挪到最左/右边
	void move(char ch, int pos)
	{
		// 先删除pos位置(l和r)
		pop(pos);
		// 设置pos位置的l和r
		if (ch == 'L')
		{
			l[pos] = 0;
			r[pos] = r[0];
			l[r[0]] = pos;
			r[0] = pos;
		}
		else
		{
			l[pos] = l[1];
			r[pos] = 1;
			r[l[1]] = pos;
			l[1] = pos;
		}
	}

private:
	int e[MAX];// 节点数据
	int l[MAX];// 记录当前节点的左节点
	int r[MAX];// 记录当前节点的右节点
	int index;// 记录e下一个要插入的位置
};

int main()
{
  int n, m;
  cin >> n >> m;
  mylist list;
  // 放数据
  for(int i = 1; i <= n; i++)
  {
    list.push_back(i);
  }
  char ch;
  int num;
  // 挪动数据
  while(m--)
  {
    cin >> ch >> num;
    list.move(ch, num + 1);
  }
  list.print();
  return 0;
}

到了这里,关于蓝桥杯第十三届决赛真题-左移右移的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第十三届蓝桥杯国赛 Web 前端组(大学组) 真题练习及答案解析

    考点:数组方法 思路:利用splice()方法 考点:flex布局 思路:照着写就行 考点: DOM 操作 思路:1 先做需求:隐藏开始按钮,方格上的图片显示后又隐藏。 2 再做第一次点击图片翻转效果。 3 做第二次点击的逻辑判断,若水果相同则,进行消除,加分操作,水果不同,进行隐

    2024年02月06日
    浏览(40)
  • 【蓝桥杯选拔赛真题30】C++字母转换 第十三届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析

    目录 C/C++字母转换 一、题目要求 1、编程实现 2、输入输出

    2024年01月16日
    浏览(27)
  • 第十三届蓝桥杯嵌入式国赛真题(基于HAL库的巨简代码+超级详解)

    相关说明: 开发板:CT117E-M4(STM32G431RBT6) 开发环境: CubeMX+Keil5 涉及题目:第十三届蓝桥杯嵌入式国赛真题 难点:双路AD测量电压、输入捕获测频率、LCD屏幕翻转、冒泡法、初始上电判断、按键长短按 CubeMX配置、主要函数代码及说明: 1.使能外部高速时钟: 2.配置时钟树:

    2023年04月09日
    浏览(43)
  • 第十三届蓝桥杯省赛与国赛真题题解大汇总(十四届参赛者必备)

      大家好,我是执梗。本文汇总了我写的第十三届蓝桥杯所有省赛真题与国赛真题,会针对每道题打出我自己的难度评星⭐️,也会给出每道题的算法标签,帮助大家更有针对性的去学习和准备,当然许多题目由于难度或时间的原因暂未更新,如果有不懂的问题也可以在评

    2024年02月11日
    浏览(64)
  • 第十三届蓝桥杯嵌入式省赛第二场真题(基于HAL库的巨简代码+超级详解)

    相关说明: 开发板:CT117E-M4(STM32G431RBT6) 开发环境: CubeMX+Keil5 涉及题目:第十三届蓝桥杯嵌入式省赛第二场真题 CubeMX配置、主要函数代码及说明: 1.使能外部高速时钟: 2.配置时钟树: 3.GPIO: 4.TIM2(通道2 PA1输出脉冲信号): 5.UART: 6.NVIC优先级配置    博主参加的是第一场

    2023年04月09日
    浏览(34)
  • 【蓝桥杯嵌入式】蓝桥杯第十二届省赛程序真题,真题分析与代码讲解

    🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏 🎏【蓝桥杯嵌入式】蓝桥杯第十届省赛真题 🎏【蓝桥杯嵌入式】蓝桥杯第十三届省赛程序真题 🪔本系列专栏 -  

    2023年04月15日
    浏览(37)
  • 蓝桥杯-左移右移(2022国赛)

      小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,… N 。   之后小蓝对这个数组进行了 M 次操作, 每次操作可能是以下 2 种之一: 左移 x , 即把 x 移动到最左边。 右移 x , 即把 x 移动到最右边。   请你回答经过 M 次操作之后, 数组从左到右每个数是多少? 输入格

    2023年04月08日
    浏览(27)
  • 第十三届蓝桥杯经验分享

    当时报名参加蓝桥杯,是为了以后工作能有个证吧,但苦于大三 没有时间准备 ,就这样轻装上阵, 一点儿没复习 , 真题也没做,练习也没整 , 一篇经验贴也没仔细看 ,结果还拿了个省三,不知道是不是参与奖哈哈。但作为过来人,还是有点经验的,特来分享 ヽ(✿゚▽゚

    2024年02月15日
    浏览(32)
  • 蓝桥杯十三届真题—全排列价值

    题目描述 对于一个排列 A = (a1, a2, · · · , an),定义价值 C i = ∣ a j ∣ j i , a j a i ∣ C_i = |{a_j | j i, a_j a_i}| C i ​ = ∣ a j ​ ∣ j i , a j ​ a i ​ ∣ 。定义 A 的价值为 ∑ i = 1 n C i sum_{i=1}^nC_i ∑ i = 1 n ​ C i ​ 给定 n,求 1 至 n 的全排列中所有排列的价值之和。 输入 输入一行包

    2023年04月13日
    浏览(28)
  • 第十三届蓝桥杯省赛Python 组

    本次所有代码均存放于仓库: Github :GxlHus/Algorithm at 蓝桥杯 (github.com) Gitee :Algorithm: 算法解题 - Gitee.com 原题目:第十三届蓝桥杯大赛软件赛省赛_PB.pdf · AYO/Algorithm - Gitee.com 本次省赛题目总体来说不难,总体质量比较高,尤其是后边几道题,虽然能轻易做出来,但是想跑通所

    2023年04月17日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包