csu 1329 一行盒子(数组模拟链表)

来源:互联网 发布:噩梦 知乎 编辑:程序博客网 时间:2024/05/21 14:54
Description
你有一行盒子,从左到右依次编号为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。

Input
输入包含不超过10组数据,每组数据第一行为盒子个数n和指令条数m(1<=n,m<=100,000),以下m行每行包含一条指令。

Output
每组数据输出一行,即所有奇数位置的盒子编号之和。位置从左到右编号为1~n。

Sample Input
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
Sample Output
Case 1: 12
Case 2: 9

Case 3: 2500050000

#include <iostream>#include <cstdio>#include <cstring>#define maxn 1001000#define ll long longusing namespace std;int nex[maxn],pre[maxn],n,m,k,tim;int *tep,*tep2;void init_nex_pre(){    for (int i=1; i<=n; i++)        nex[i]=i+1,pre[i]=i-1;    nex[n]=0;}void dele(int x){    int k1=pre[x],k2=nex[x];    nex[k1]=k2,pre[k2]=k1;}void inser(int k1,int mid,int k2){    nex[k1]=mid,nex[mid]=k2;    pre[k2]=mid,pre[mid]=k1;}void SWAP(int x,int y){    int k1=pre[x],k2=nex[x],k3=pre[y],k4=nex[y];    if (k2==y)//考虑xy相邻的情况    {        nex[k1]=y,nex[y]=x,nex[x]=k4;        pre[k4]=x,pre[x]=y,pre[y]=k1;    }    else if (k4==x)//考虑xy相邻的情况    {        nex[k3]=x,nex[x]=y,nex[y]=k2;        pre[k2]=y,pre[y]=x,pre[x]=k3;    }    else    {        nex[k1]=y,nex[y]=k2,pre[y]=k1,pre[k2]=y;        nex[k3]=x,nex[x]=k4,pre[x]=k3,pre[k4]=x;    }}int main(){    int cod,x,y,cas=0;    while (cin>>n>>m)    {        tim=0;        init_nex_pre();///初始        while (m--)        {            cin>>cod;///输入操作            if (cod==4)                tim++;//这里只要记录首位交换了多少次哦            else            {                cin>>x>>y; ///输入即将进行的转换                if (cod<3 && tim&1)///如果code<3且time为奇数                    cod=3-cod;//如果交换了奇数次,那么本来应该插在前面就相当于是现在应该插在后面,                //T_T不好怎么表达,自己理解一下就懂了。                if (cod==1)                {                    dele(x);                    k=pre[y];                    inser(k,x,y); ///x插在y左边                }                else if (cod==2)                {                    dele(x);                    k=nex[y];                     inser(y,x,k); ///x插在y右边                }                else if (cod==3) SWAP(x,y); ///交换            }        }       if (tim&1) ///如果4交换的是奇数次            tep=pre,tep2=nex;        else        tep=nex,tep2=pre;///偶数次的话         for (int i=1; i<=n; i++)        {            if (tep2[i]==0)            {                ll ans=0;                for (int k=1; i; i=tep[i],k++)                    {                        if (k&1)///转化为二进制的低位与1相与,如果为1 则为k为奇数                           ans+=i;                    }                cout<<"Case "<<++cas<<": "<<ans<<endl;                break;            }        }    }    return 0;}


0 0
原创粉丝点击