CSUOJ 1982 2013:移动硬盘

1982: 小M的移动硬盘

2013: 珂朵莉的移动硬盘

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

Hint

双向链表+数组存储节点位置+头尾指针,写起来容易,调试起来吐血(所以还是写得差啊)。肯定有别的方法,留给未来的自己吧。(未来的自己:这锅我不背)
还有就是每次一涉及链表都会先RE几次,思维还是不够缜密啊,指针真是个磨人的玩意。
运行结果

#include<stdio.h>
#include<stdlib.h>
struct node {
	struct node *next;
	struct node *pre;
	int data;
};
struct node *phead;
struct node *pEnd;
int T;
int m, n, operation, u, v;
struct node* create(int n, struct node *phead);
void destroy(int n, struct node *phead);
/*
 *	遍历查找,TLE,改用数组存储位置
 *	struct node* searchBefore(int n, struct node *phead, int result);
 */
struct node *a[300005];
struct node* process1(int n, struct node *phead, int u);
struct node* process2(int n, struct node *phead, int u);
struct node* process3(int n, struct node *phead, int u, int v);
int main()
{
	scanf("%d", &T);
	for (int q = 0; q < T; q++)
	{
		struct node *phead = NULL;
		pEnd = NULL;
		scanf("%d%d", &n, &m);
		if (n == 1)
		{
			for (int i = 0; i < m; i++)
			{
				scanf("%d", &operation);
				if (1 == operation || 2 == operation)
				{
					scanf("%d", &u);
				}
				else
				{
					scanf("%d%d", &u, &v);
				}
			}
			printf("1\n");
		}
		else
		{
			phead = create(n, phead);
			for (int i = 0; i < m; i++)
			{
				scanf("%d", &operation);
				if (1 == operation)
				{
					scanf("%d", &u);
					phead = process1(n, phead, u);
				}
				else if (2 == operation)
				{
					scanf("%d", &u);
					phead = process2(n, phead, u);
				}
				else
				{
					scanf("%d%d", &u, &v);
					phead = process3(n, phead, u, v);
				}
			}
			struct node *p = phead;
			for (int i = 0; i < n; i++)
			{
				if (i != 0)
					printf(" ");
				printf("%d", p->data);
				p = p->next;
			}
			printf("\n");
			destroy(n, phead);
		}
	}
	return 0;
}
struct node* create(int n, struct node *phead)
{
	struct node *newNode;
	newNode = malloc(sizeof(struct node));
	newNode->data = n;
	newNode->next = NULL;
	phead = newNode;
	a[n] = newNode;
	pEnd = newNode;
	for (int i = n - 1; i > 0; i--)
	{
		newNode = malloc(sizeof(struct node));
		newNode->data = i;
		newNode->next = phead;
		phead = newNode;
		a[i] = newNode;
		a[i + 1]->pre = newNode;
	}
	a[1]->pre = NULL;
	return phead;
}
void destroy(int n, struct node *phead)
{
	struct node *temp;
	for (int i = 1; i <= n; i++)
	{
		temp = phead;
		phead = phead->next;
		free(temp);
	}
	pEnd = NULL;
}
/*
 *struct node* searchBefore(int n, struct node *phead, int result)
 *{
 *	//在该题中一定能搜索成功,不考虑搜索失败
 *	for (; (phead->next)->data != result; phead = phead->next);
 *	return phead;
 *}
 */
struct node* process1(int n, struct node *phead, int u)
{
	if (phead->data == u)
		return phead;
	else if (pEnd->data == u)
	{
		pEnd = a[u]->pre;
		a[u]->pre->next = NULL;
		phead->pre = a[u];
		a[u]->next = phead;
		phead = a[u];
		a[u]->pre = NULL;
		return phead;
	}
	else
	{
		a[u]->pre->next = a[u]->next;
		a[u]->next->pre = a[u]->pre;
		phead->pre = a[u];
		a[u]->next = phead;
		phead = a[u];
		a[u]->pre = NULL;
		return phead;
	}
}
struct node* process2(int n, struct node *phead, int u)
{
	if (pEnd->data == u)
	{
		return phead;
	}
	else if (phead->data == u)
	{
		phead = a[u]->next;
		phead->pre = NULL;
		a[u]->next = NULL;
		a[u]->pre = pEnd;
		pEnd->next = a[u];
		pEnd = a[u];
		return phead;
	}
	else
	{
		a[u]->pre->next = a[u]->next;
		a[u]->next->pre = a[u]->pre;
		a[u]->next = NULL;
		a[u]->pre = pEnd;
		pEnd->next = a[u];
		pEnd = a[u];
		return phead;
	}
}
struct node* process3(int n, struct node *phead, int u, int v)
{
	if (phead->data == u)
	{
		phead = a[u]->next;
		a[u]->next->pre = NULL;
		if (pEnd->data == v)
		{
			pEnd = a[u];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			a[u]->pre = a[v];
		}
		else
		{
			a[v]->next->pre = a[u];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			a[u]->pre = a[v];
		}
		return phead;
	}
	else if (phead->data == v)
	{
		if (pEnd->data == u && a[u]->pre->data != v)
		{
			pEnd = a[u]->pre;
			a[u]->pre->next = NULL;
			a[v]->next->pre = a[u];
			a[u]->pre = a[v];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			return phead;
		}
		else if (pEnd->data == u && a[u]->pre->data == v)
		{
			return phead;
		}
		else 
		{
			a[u]->pre->next = a[u]->next;
			a[u]->next->pre = a[u]->pre;
			a[v]->next->pre = a[u];
			a[u]->pre = a[v];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			return phead;
		}	
	}
	else
	{
		if (pEnd->data == v)
		{
			a[u]->pre->next = a[u]->next;
			a[u]->next->pre = a[u]->pre;
			pEnd = a[u];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			a[u]->pre = a[v];
			return phead;
		}
		else if (pEnd->data == u && a[u]->pre->data != v)
		{
			a[u]->pre->next = a[u]->next;
			pEnd = a[u]->pre;
			a[v]->next->pre = a[u];
			a[u]->pre = a[v];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			return phead;
		}
		else if (pEnd->data == u && a[u]->pre->data == v)
		{
			return phead;
		}
		else
		{
			a[u]->pre->next = a[u]->next;
			a[u]->next->pre = a[u]->pre;
			a[v]->next->pre = a[u];
			a[u]->pre = a[v];
			a[u]->next = a[v]->next;
			a[v]->next = a[u];
			return phead;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值