洛谷B3688:[语言月赛202212]旋转排列(新解法:deque双端队列)

题目描述

我们称一个数列 p 是一个长度为 n 的排列,当且仅当 p 满足如下条件:

  1. p 的长度为 n;
  2. 1,2,3,...n 这 n 个数在 p 中均恰好出现一次。

对于一个排列 p,定义一次"shift"操作是指:将 p 里的每一个数字都依次向后移动一位,并把 p 的最后一个数字移动到开头去。

例如,若排列 p 初始时为 1,4,2,3,则"shift"一次以后将变为 3,1,4,2

现在,给定一个长度为 n 的排列 p,请你按照如下规定循环操作:

  1. 对当前的排列 p 做一次"shift"操作;
  2. 输出本次"shift"以后的排列 p;
  3. 判断排列 p 的最后一个数字是否是 n,如果是,则结束循环操作;否则回到 1 继续操作。

提示:请严格按照题目给出的顺序进行循环操作。

输入

第一行是一个整数,表示排列 p 的长度 n。

第二行有 n 个整数表示排列 p,第 i 个整数表示 pi​。

输出

对于每次操作的第二条"输出"操作,请你输出一行 n 个整数,按顺序表示当前排列的每个数,一行中相邻两个数之间用一个空格隔开。

样例输入输出

输入 #1

复制代码
4
1 4 2 3

输出 #1

复制代码
3 1 4 2
2 3 1 4

输入 #2

复制代码
3
1 2 3

输出 #2

复制代码
3 1 2
2 3 1
1 2 3

输入 #3

复制代码
10
1 7 6 5 8 4 3 9 10 2

输出 #3

复制代码
2 1 7 6 5 8 4 3 9 10
思路

题目中的操作,可以理解为把序列中最后一个元素移到最前面,直到最后一个元素是n

在STL中,有一种容器可以很方便地进行此操作:deque(双端队列)

先介绍一下deque,deque的常用操作有:

01.元素访问

cpp 复制代码
deque<int>d={1,2,3,4,5};
d[2];           //下标访问,不检查边界,O(1)
d.at(2);        //带边界检查的访问,越界抛出out_of_range,O(1)
d.front();      //访问第一个元素,O(1)
d.back();       //访问最后一个元素,O(1)

02.容量操作

cpp 复制代码
d.empty();      // 判断是否为空,O(1)
d.size();       // 返回元素个数,O(1

03.修改操作

cpp 复制代码
//插入
d.push_back(6);          // 尾部添加,O(1)
d.push_front(0);         // 头部添加,O(1)
d.insert(pos,val);       // 在指定位置插入,O(n)
d.insert(pos,n,val);     // 插入n个val
d.insert(pos,first,last);// 插入迭代器区间元素

//删除
d.pop_back();         // 删除尾部元素,O(1)
d.pop_front();        // 删除头部元素,O(1)
d.erase(pos);         // 删除指定位置元素,O(n)
d.erase(first, last); // 删除区间元素,O(n)
d.clear();            // 清空所有元素,O(n)

//其他
d.assign(5, 10);   // 重新赋值为5个10
d.assign({1,2,3}); // 重新赋值为初始化列表
d.swap(d2);        // 交换两个deque的内容
d.resize(10);      // 改变大小
d.resize(10, 5);   // 改变大小并用5填充新位置

关于题目,还有一个细节:

因为题目是先做操作才判断,所以循环时应该用do......while循环 !!!

至此题目分析完毕,下面展示步骤:

STEP 1:按要求输入,把输入的元素插进双端队列中。

STEP 2:do......while循环,每次记上然后删除队尾元素,插入队头。

STEP 3:for:循环遍历输出队列元素即可。

代码
cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int n,a;
deque<int>q;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    	cin>>a;
    	q.push_back(a);
	}
	do
	{
		a=q.back();
		q.pop_back();
		q.push_front(a);
		for(int v:q)
		{
			cout<<v<<' ';
		}
		cout<<'\n';
	}while(q.back()!=n);
    return 0;
}
运行结果

感谢阅读,我们下期再会。

如果您喜欢本文,请您点赞、收藏加关注,以防你找不到回来的路,谢谢!

相关推荐
Chester_19999 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
裕晟资质规划10 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
会周易的程序员10 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
小灰灰搞电子11 小时前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
QT界面美化性能优化11 小时前
QT+AI:使用AI技术为QT应用程序赋能
c++·人工智能·qt·opencv·qt教程·qt6.3
en.en..11 小时前
C语言 标准输入 / 输出缓冲区
算法
吃好睡好便好13 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球13 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
小灰灰搞电子14 小时前
C++ 引用折叠详解
c++
专注仿真14 小时前
Spring AI 实现智能对话系统项目指南
数据结构·spring·机器学习