目录
一、题目描述
问题描述
小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,……N 。
之后小蓝对这个数组进行了 M 次操作, 每次操作可能是以下 2 种之一:
左移 x, 即把 x 移动到最左边。
右移 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%的评测用例, 1≤N,M≤10000.
对于 100% 的评测用例, 1≤N,M≤200000,1≤x≤N.
运行限制
- 最大运行时间:3s
- 最大运行内存: 512M
二、解题思路
最初思路:
用一个大小为N+1的数组 arr,下标从 1 开始,依次存放1——N,然后用另一个数组 flag 用于更新对应arr下标的信息,对flag数组进行排序,arr对应变换位置。
L_flag 初始化为0(小于arr数组中的任意一个数) , R_flag 初始化为N+1(大于arr数组中的任意一个数),而当左移x时,更新flag对应下标为x的信息,将 L_flag - - 存入,而当右移x时,将 R_flag ++ 存入。结束后,需要对flag的数组进行排序,排序的过程中,arr数组与flag数组相对应的下标一起交换位置,最后输出arr数组。
算法实现中的问题:
1、根据题意,满足N的范围时,会造成预定义的arr数组过大。
采用malloc()函数 动态内存分配空间,输入N个大小的数组,就分配N个大小的内存。
2、最后对flag数组进行排序时,所采用的的算法排序执行的效率。刚开始采用简单选择排序,当数组过大时,执行时间过长,超时。
利用<stdlib.h>的库函数中的 qsort函数进行排序,qsort函数采用的是快速排序法,会节省时间。
//简单选择排序 void sort(int* arr, int* flag, int N) { for (int i = 1; i <= N - 1; i++) { int k = i; for (int j = i+1; j <= N; j++) { if (flag[j]<flag[k]) { k = j; } } if (k != i) { int temp1 = flag[i]; int temp2 = arr[i]; flag[i] = flag[k]; flag[k] = temp1; arr[i] = arr[k]; arr[k] = temp2; } } }
思路优化:
采用结构体类型的数组,结构体存放数值,以及标记的信息。对结构体类型的数组中的flag排序时,对应的结构体类型的元素也同样变换位置。
![]()
三、算法实现
#include<stdio.h>
#include<stdlib.h>
typedef struct Node {
int data;
int flag;
}LNode;
int compare(const void* p, const void* q)
{
return ((LNode*)p)->flag > ((LNode*)q)->flag ? 1 : 0;
}
int main()
{
int i, j, N, M, d, L_flag, R_flag;
char direction = ' ';
scanf("%d", &N);
scanf("%d", &M);
L_flag = 0;
R_flag = N + 1;
LNode* arr=(LNode*)malloc(sizeof(LNode) * (N + 1));
for (i = 1; i <= N; i++)
{
arr[i].data = i;
arr[i].flag = i;
}
for (j = 1; j <= M; j++)
{
scanf(" %c", &direction);
scanf("%d", &d);
if (direction == 'L')
arr[d].flag = L_flag--;
if (direction == 'R')
arr[d].flag = R_flag++;
}
qsort(arr+1,N,sizeof(LNode),compare);
for (i = 1; i <= N; i++)
printf("%d ", arr[i].data);
return 0;
}
执行结果: