第一次对数组实现双向链表的练习,理解了发现数组实现真方便…
题目: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;