csu 1329 一行盒子(双向链表模拟)

静态模拟双向链表,只要写的仔细一点就没有难度,自己就是因为不仔细写了很长时间。。

注意:

1.修改两个元素时不但要考虑这两个元素本身,还要考虑他们的前驱和后继结点的变化。

2.交换操作注意两个相邻元素交换是特殊情况。

3.反转整个表不需要每次都转,记录下转了多少次(转偶数次等于没转),当前如果被反转了那么1操作就会变成2操作,纸上写一下就知道了

4.输出用lld


代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define maxn 100005
using namespace std;

int Left[maxn];
int Right[maxn];
int n;
int Start,End;
int pos[maxn];

void check(int a,int b){
    if(Right[a]==n+1) End=a;
    if(Right[b]==n+1) End=b;
    if(Left[a]==0) Start=a;
    if(Left[b]==0) Start=b;
    
}

void del(int a){
    int t1=Left[a],t2=Right[a];
    Left[t2]=t1;
    Right[t1]=t2;
    check(t1,t2);
}

void setright(int a,int b){
    del(a);
    Left[Right[b]]=a;
    Right[a]=Right[b];
    Right[b]=a;
    Left[a]=b;
    check(a,b);
}

void setleft(int a,int b){
    del(a);
    Right[Left[b]]=a;
    Left[a]=Left[b];
    Left[b]=a;
    Right[a]=b;
    check(a,b);
}

void Swap(int a,int b){
    int l1=Left[a],l2=Left[b],r1=Right[a],r2=Right[b];
    if(l1==b){
        Left[a]=Left[b];
        Left[b]=a;
        Right[a]=b;
        Right[b]=r1;
        Left[r1]=b;
        Right[l2]=a;
    }
    else if(l2==a){
        Left[b]=Left[a];
        Left[a]=b;
        Right[b]=a;
        Right[a]=r2;
        Left[r2]=a;
        Right[l1]=b;
    }
    else {
        Left[a]=l2;Left[b]=l1;Right[a]=r2;Right[b]=r1;
        Left[r1]=b;Right[l1]=b;Left[r2]=a;Right[l2]=a;
    }
    check(a,b);
}

int main(){
    int flag=1;
    int m;
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++){
            Left[i]=i-1;
            Right[i]=i+1;
        }
        Left[0]=-1;
        Start=1,End=n;
        int flip=0;
        while(m--){
            int t;
            scanf("%d",&t);
            if(t==1){
                int a,b;
                scanf("%d%d",&a,&b);
                if(flip%2==0) setleft(a,b);
                else setright(a,b);
            }

            else if(t==2){
                int a,b;
                scanf("%d%d",&a,&b);
                if(flip%2==0) setright(a,b);
                else setleft(a,b);
            }
            else if(t==3){
                int a,b;
                scanf("%d%d",&a,&b);
                Swap(a,b);

            }
            else flip++;
  
        }
        LL res=0;
        if(flip%2==0){
            int cur=Start;
            int k=1;
            while(cur!=n+1){
                if(k%2) res+=cur;
                cur=Right[cur];
                ++k;

            }
        }
        else {
            int cur=End;
            int k=1;
            while(cur!=0){
                if(k%2) res+=cur;
                cur=Left[cur];
                ++k;

            }
        }
        printf("Case %d: %lld\n",flag++,res);
    }
    return 0;
}















你可能感兴趣的:(链表)