CSU-1982 小M的移动硬盘

CSU-1982 小M的移动硬盘

Description

最近小M买了一个移动硬盘来储存自己电脑里不常用的文件。但是他把这些文件一股脑丢进移动硬盘后,觉得这些文件似乎没有被很好地归类,这样以后找起来岂不是会非常麻烦?
小M最终决定要把这些文件好好归类,把同一类地移动到一起。所以现在小M有了这几种操作:
1 u 表示把编号为u的文件放到最上面
2 u 表示把编号为u的文件放到最下面
3 u v 表示把编号为u的文件放到编号为v的文件的后面
已知在最开始的时候,1号文件到n号文件从上往下排布
现在小M已经给出了他所进行的所有操作,你能告诉他操作之后的序列是会变成什么样子吗?

Input

第一行为一个数字T(T<=10)表示数据组数
第二行为两个数字n、m(1<=n,m<=300000)表示序列长度和小M的操作次数
接下来m行每行两个或三个数字,具体含义见题面
保证数据合法

Output

输出一行表示小M操作结束后的序列

Sample Input

1
10 5
1 5
2 3
2 6
3 4 8
3 1 3

Sample Output

5 2 7 8 4 9 10 3 1 6

题解

也是一道水题,但却WA了很多发,这题用数组模拟双向链表即可,先贴一开始WA的代码

#include<bits/stdc++.h>
#define maxn 300050
using namespace std;
struct node {
	int l, r;
} a[maxn];
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, m;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++) {
			a[i].l = i - 1;
			a[i].r = i + 1;
		}
		int head = 1, tail = n;
		for (int i = 1; i <= m; i++) {
			int q;
			scanf("%d", &q);
			if (q == 1) {
				int x;
				scanf("%d", &x);
				if (x == head) continue;
				if (x == tail) tail = a[x].l;
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[head].l = x;
				a[x].l = 0;
				a[x].r = head;
				head = x;
			}
			if (q == 2) {
				int x;
				scanf("%d", &x);
				if (x == tail) continue;
				if (x == head) head = a[x].r;
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[tail].r = x;
				a[x].l = tail;
				a[x].r = n + 1;
				tail = x;
			}
			if (q == 3) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (x == y) continue;
				if (x == head) {
					head = a[x].r;
				}
				if (y == tail) {
					tail = x;
				}
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[x].r = a[y].r;
				a[a[y].r].l = x;
				a[x].l = y;
				a[y].r = x;
			}
		}
		int now = head;
		for (int i = 1; i < n; i++) {
			printf("%d ", now);
			now = a[now].r;
		}
		printf("%d
", now);
	}
	return 0;
}
/**********************************************************************
	Problem: 1982
	User: Artoriax
	Language: C++
	Result: WA
**********************************************************************/

这个代码只有一点没注意到,即在q==3时,x处于tail时也会导致tail变化,很容易想的一个点,但却WA了很多次,然后去网上搜题解,用a[0]表示链表头,用a[n + 1]表示表尾才AC, 之后对拍一发才发现这个愚蠢的错误。


网上题解版:

#include<bits/stdc++.h>
#define maxn 300050
using namespace std;
struct node {
	int l, r;
} a[maxn];
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, m;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++) {
			a[i].l = i - 1;
			a[i].r = i + 1;
		}
		a[0].r = 1;
		a[n + 1].l = n;
		for (int i = 1; i <= m; i++) {
			int q;
			scanf("%d", &q);
			if (q == 1) {
				int x;
				scanf("%d", &x);
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[x].l = 0;
				a[x].r = a[0].r;
				a[a[0].r].l = x;
				a[0].r = x;
			}
			if (q == 2) {
				int x;
				scanf("%d", &x);
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[x].r = n + 1;
				a[x].l = a[n + 1].l;
				a[a[n + 1].l].r = x;
				a[n + 1].l = x;
			}
			if (q == 3) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (x == y) continue;
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[x].r = a[y].r;
				a[a[y].r].l = x;
				a[x].l = y;
				a[y].r = x;
			}
		}
		int now = a[0].r;
		for (int i = 1; i < n; i++) {
			printf("%d ", now);
			now = a[now].r;
		}
		printf("%d
", now);
	}
	return 0;
}
/**********************************************************************
	Problem: 1982
	User: Artoriax
	Language: C++
	Result: AC
	Time:556 ms
	Memory:4368 kb
**********************************************************************/

自己改正版:

#include<bits/stdc++.h>
#define maxn 300050
using namespace std;
struct node {
	int l, r;
} a[maxn];
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		int n, m;
		scanf("%d%d", &n, &m);
		for (int i = 1; i <= n; i++) {
			a[i].l = i - 1;
			a[i].r = i + 1;
		}
		int head = 1, tail = n;
		for (int i = 1; i <= m; i++) {
			int q;
			scanf("%d", &q);
			if (q == 1) {
				int x;
				scanf("%d", &x);
				if (x == head) continue;
				if (x == tail) tail = a[x].l;
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[head].l = x;
				a[x].l = 0;
				a[x].r = head;
				head = x;
			}
			if (q == 2) {
				int x;
				scanf("%d", &x);
				if (x == tail) continue;
				if (x == head) head = a[x].r;
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[tail].r = x;
				a[x].l = tail;
				a[x].r = n + 1;
				tail = x;
			}
			if (q == 3) {
				int x, y;
				scanf("%d%d", &x, &y);
				if (x == y) continue;
				if (a[y].r == x) continue;
				if (x == head) {
					head = a[x].r;
				}
				if (x == tail) {
					tail = a[x].l;
				}
				if (y == tail) {
					tail = x;
				}
				a[a[x].l].r = a[x].r;
				a[a[x].r].l = a[x].l;
				a[x].r = a[y].r;
				a[a[y].r].l = x;
				a[x].l = y;
				a[y].r = x;
			}
		}
		int now = head;
		for (int i = 1; i < n; i++) {
			printf("%d ", now);
			now = a[now].r;
		}
		printf("%d
", now);
	}
	return 0;
}
/**********************************************************************
	Problem: 1982
	User: Artoriax
	Language: C++
	Result: AC
	Time:560 ms
	Memory:4368 kb
**********************************************************************/

原文地址:https://www.cnblogs.com/artoriax/p/10349153.html