左移右移【蓝桥杯国赛】

该问题描述了一个长度为N的数组,初始顺序为1到N,然后进行M次左移或右移操作。程序通过链表实现,动态更新数组元素的位置。输入包括操作次数和每次操作类型,输出是操作后的数组顺序。示例展示了具体的操作过程和代码实现。
摘要由CSDN通过智能技术生成

左移右移

题目描述

小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,…N 。之后小蓝对这个数组进行了 M 次操作, 每次操作可能是以下 2 种之一:

  1. 左移 x, 即把 x 移动到最左边。

  2. 右移 x, 即把 x 移动到最右边。

请你回答经过 M 次操作之后, 数组从左到右每个数是多少?

输入格式

第一行包含 2 个整数, N* 和 M

以下 M 行每行一个操作, 其中 “L x "表示左移 x,"Rx "表示右移 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%50% 的评测用例, 1≤N,M≤10000.

对于 100%100% 的评测用例, 1≤N,M≤200000,1≤xN.

代码

#include<stdio.h>
int sign[200004][3];
int main(){
	
	int n,m,t;
	char x;

	scanf("%d %d\n",&n,&m);
	
	//初始化建立数组链表 
	for(int i=0;i<=n+1;i++){
		sign[i][0]=i;     //每一个一维数组第一个表示要存入的数 
		sign[i][1]=i-1;   //第二个表示前一个节点的序号 (前指针) 
		sign[i][2]=i+1;   //第三个表示后一个节点的序号 (后指针) 
	}

	int l,r;	
	while(m--){

		//例如数组初始化为 1 2 3 4 5 (数组中实际存放为 0 1 2 3 4 5 6) 
		scanf("%c %d\n",&x,&t);
		if(x=='L'){                //例如输入 L 3 
			l=sign[t][1];          //将节点 3 的前一个节点赋值给 l 
			r=sign[t][2];          //将节点 3 的后一个节点赋值给 r 
			
			//删除节点 3(并不是真删除,只是修改前后指针使节点3不在原来的位置) 
			sign[l][2]=r;          //将节点 3 的前一个节点(节点 2) 的后指针指向节点 4 
			sign[r][1]=l;          //将节点 3 的后一个节点(节点 4) 的前指针指向节点 2 
			
			//将节点 3 插入前面 
			sign[t][1]=0;             //将节点 3 的前指针指向节点 0  
			sign[t][2]=sign[0][2];    //将节点 3 的后指针指向节点 0 的后继节点(节点 1) 
 			sign[sign[0][2]][1]=t;    //将节点 0 的后继节点(节点 1)的前指针指向节点 3  
			sign[0][2]=t;             //将节点 0 的后指针指向节点 3 
		
		}
		else{                       //例如输入 R 3 
			l=sign[t][1];
			r=sign[t][2];
			
			sign[l][2]=r;
			sign[r][1]=l;
			
			//将节点 3 插入后面 
			sign[t][2]=n+1;            //将节点 3 的后指针指向节点 6 
			sign[t][1]=sign[n+1][1];   //将节点 3 的前指针指向节点 6 的前驱节点(节点 5) 
			sign[sign[n+1][1]][2]=t;   //将节点 6 的前驱节点(节点 5)的后指针指向节点 3 
			sign[n+1][1]=t;            //将节点 6 的前指针指向节点 3 
			
		}
	}
	int i=sign[0][2];
  	while(i<=n){
    	printf("%d ",i);
    	i=sign[i][2];
  	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值