zoukankan      html  css  js  c++  java
  • UVA12657 移动盒子 Boxes in a Line 题解(双向链表)

    题目链接

    题目思路

    本质上就是模拟一下双向链表

    显然操作4是要做标记的

    如果现在是反转那么操作1变为操作2,操作2变为操作1

    还有操作3中需要特判相邻的情况

    代码

    #include<cstdio>
    #include<iostream>
    #define fi first
    #define se second
    #define debug cout<<"I AM HERE"<<endl;
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5,inf=0x3f3f3f3f,mod=1e9+7;
    const double eps=1e-6;
    typedef pair<ll,int> pli;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    int n,m;
    int l[maxn],r[maxn];
    int ca;
    void link(int a,int b){
        r[a]=b;
        l[b]=a;
    }
    void link(int a,int b,int c){
        r[a]=b;
        l[b]=a;
        r[b]=c;
        l[c]=b;
    }
    signed main(){
        while(scanf("%d%d",&n,&m)==2){
            for(int i=1;i<=n;i++){
                l[i]=i-1;
                r[i]=i+1;
            }
            r[n]=0;
            l[0]=1,r[0]=n;
            bool flag=1;
            for(int i=1,opt,x,y;i<=m;i++){
                scanf("%d",&opt);
                if(opt==4){
                    flag=(!flag);
                }else{
                    scanf("%d%d",&x,&y);
                    if((opt==1||opt==2)&&(!flag)){
                        opt=3-opt;
                    }
                    if(opt==1){
                        //x放y左边
                        if(l[y]==x) continue;
                        link(l[x],r[x]);
                        link(l[y],x,y);
                    }else if(opt==2){
                        //x放y右边
                        if(r[y]==x) continue;
                        link(l[x],r[x]);
                        link(y,x,r[y]);
                    }else if(opt==3){
                        if(r[x]!=y&&l[x]!=y){
                            int lastl=l[y],lastr=r[y];
                            link(l[x],y,r[x]);
                            link(lastl,x,lastr);
                            continue;
                        }
                        if(r[y]==x) swap(x,y);
                        
                        if(r[x]==y){
                            int lastlx=l[x];
                            l[r[y]]=x;
                            r[l[x]]=y;
                            r[x]=r[y];
                            l[x]=y;
                            r[y]=x;
                            l[y]=lastlx;
    
                        }
                    }
                }
            }
            int beg;// 起点
            for(int i=1;i<=n;i++){ //找起点
                if(flag&&l[i]==0){
                    beg=i;
                }else if(!flag&&r[i]==0){
                    beg=i;
                }
            }
            int cnt=1;
            ll ans=0;
            if(flag){
                while(1<=beg&&beg<=n){
                    if(cnt%2==1) ans+=beg;
                    beg=r[beg];
                    cnt++;
                }
            }else{
                 while(1<=beg&&beg<=n){
                    if(cnt%2==1) ans+=beg;
                    beg=l[beg];
                    cnt++;
                }
            }
            printf("Case %d: %lld
    ",++ca,ans);
        }
        return 0;
    }
    
    
    卷也卷不过,躺又躺不平
  • 相关阅读:
    从scanf的学习接口设计
    特现C语言编程特点的小代码,itoa,数值转换成字符串
    So many good projects for studying C programming lanuage.
    重要算法代码
    选择一本C++教材
    4412 内核模块传参数
    4412 GPIO初始化
    4412 物理地址
    4412 杂项设备
    4412 Linux设备总线
  • 原文地址:https://www.cnblogs.com/hunxuewangzi/p/14577519.html
Copyright © 2011-2022 走看看