UVA-12657 Boxes in a Line (模拟,双向链表(数组实现))

这篇博客详细介绍了如何使用数组来实现双向链表,以解决UVA-12657题目中的盒子移动问题。作者通过分析四种操作,强调了数组实现的便利性,并提供了避免特殊判断的优化思路,特别是针对操作4的反转处理。文章附带了实现代码并提醒了编写switch语句时的注意事项。
摘要由CSDN通过智能技术生成

第一次对数组实现双向链表的练习,理解了发现数组实现真方便…

题目:UVA-12657

题目描述:
你有n个盒子在桌子上的一条线上从左到右编号为1……n。你的任务是模拟四种操作

1 X Y 移动盒子编号X到盒子编号Y的左边(如果X已经在Y的左边了就忽略)

2 X Y 移动盒子编号X到盒子编号Y的右边(如果X已经在Y的右边了就忽略)

3 X Y 交换盒子编号X与盒子编号Y的位置

4 将整条线反转

操作保证合法,X不等于Y

举一个例子,如果n=6,操作 1 1 4然后就变成了2 3 1 4 5 6;再操作 2 3 5就变成了 2 1 4 5 3 6;再操作 3 1 6 就变成 2 6 4 5 3 1;最后操作4,就变成了 1 3 5 4 6 2

分析:
这题用数组实现双向链表极其便利,因为这里的编号从1~n,即是 值 ,也是 下标(可以理解为node的地址),所以不需要另外创建node数组来联系这两者,直接就能处理。

分析一下题目,1,2操作直接模拟即可,3操作最好要对X,Y相邻的情况进行特判(不知道其他方法是否可省略特判,反正我WA了 )。

操作4最为关键,如果每次都反转会花很多时间,一开始还不知道怎么处理,但其实反转只会影响操作1和操作2以及最后求和,如果反转了,操作1就变成了操作2,操作2变成了操作1,求和找奇数位置时从头到尾遍历变成从尾到头。

(还有,如果用switch语句来选择操作数,记得每个case结尾break;,不要问我为什么说这个

贴下代码(里面还有注释):

#include<cstdio>
using namespace std;
int Right[100001], Left[100001];
void link(int L, int R)    //构造一个函数来连接左右两个,可以让程序简洁明了很多
{
   
	Right[L] = R;
	Left[R] = L;
}
int main()
{
   
	int n, m,kase=1;
	while (scanf("%d%d",&n,&m)!=EOF)
	{
   
		int i, k, x, y,head,tail;
		bool flag = true;         //用来标记操作4,true不反转,false反转
		for (i = 1;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值