G - 一行盒子
你有一行盒子,从左到右依次编号为1, 2, 3,…, 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。
输入包含不超过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: 12Case 2: 9Case 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;
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;
long long 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+=(long long)p->n;
}
printf("Case %d: %lld\n",tt++,ans);
free(p);
free(pre);
free(phead);
}
return 0;
}
#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;
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;
long long 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+=(long long)p->n;
}
printf("Case %d: %lld\n",tt++,ans);
free(p);
free(pre);
free(phead);
}
return 0;
}