一行盒子
你有一行盒子,从左到右依次编号为1, 2, 3,…,n。你可以执行四种指令:
l 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。
l 2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。
l 3 X Y表示交换盒子X和Y的位置。
l 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。
输入
输入包含不超过10组数据,每组数据第一行为盒子个数n和指令条数m(1<=n,m<=100,000),以下m行每行包含一条指令。
输出
每组数据输出一行,即所有奇数位置的盒子编号之和。位置从左到右编号为1~n。
样例输入 |
|
6 4 1 1 4 2 3 5 3 1 6 4 6 3 1 1 4 2 3 5 3 1 6 100000 1 4 |
|
样例输出
Case 1: 12
Case 2: 9
Case 3: 2500050000
水题,写三个函数水过。
#include <iostream>
#include<stdio.h>
#include<string.h>
#include <algorithm>
#include <queue>
#include <queue>
#include <map>
#define MAXN 100005
using namespace std;
struct link {
int n;
struct link *nex;
struct link *pre;
};
int n,m;
link *has[110000];
//x移到y左边
void move1(int x,int y) {
(has[x]->pre)->nex=(has[x]->nex);
(has[x]->nex)->pre=has[x]->pre;
has[x]->nex = has[y];
has[x]->pre = has[y]->pre;
(has[y]->pre)->nex=has[x];
has[y]->pre = has[x];
}
//x移到y右边
void move2(int x,int y) {
(has[x]->pre)->nex=(has[x]->nex);
(has[x]->nex)->pre=has[x]->pre;//删除x结点
has[x]->nex = has[y]->nex;
has[x]->pre = has[y];
(has[y]->nex)->pre=has[x];
has[y]->nex = has[x];
}
//交换x和y
void exchange(int x,int y) {
has[x]->n=y;
has[y]->n=x;
link *h;
h=has[x];
has[x]=has[y];
has[y]=h;
}
int main() {
int tt=1,flag;
//freopen("b.in","r",stdin);
while (scanf("%d %d",&n,&m)!=EOF) {
struct link* p,*pre,*phead = NULL;
phead = (link*)malloc(sizeof(link));
pre = phead;
for (int i=1; i<=n+1; i++) {
p =(link*)malloc(sizeof(link));
p->n = i;
has[i]=p;
p->pre = pre;
pre->nex = p;
pre=p;
if (i==n+1)
p->nex = NULL;
}
p = phead;
int k,a,b;
flag = 1;
while (m--) {
scanf("%d",&k);
if (k==4) {
flag*=-1;
} else {
scanf("%d %d",&a,&b);
if(k==1&&flag==1)
move1(a,b);
else if(k==1&&flag==-1)
move2(a,b);
else if(k==2&&flag==1)
move2(a,b);
else if(k==2&&flag==-1)
move1(a,b);
else if(k==3)
exchange(a,b);
}
}
p = phead;
int o;
__int64 ans=0;
if(n%2==0&&flag==-1)
o=0;
else o=1;
int num=0;
while (p->nex!=NULL&&p->nex->n<=n) {
p=p->nex;
num++;
// printf("%d\n",p->n);
if(num%2==o)
ans+=(__int64)p->n;
}
printf("Case %d: %I64d\n",tt++,ans);
free(p);
free(pre);
free(phead);
}
return 0;
}