UVA-12657 Box in line

本题由于用普通数组时间耗费太大,又考虑到左右关系,使用双向链表;



使用双向链表转移时  需注意:  移动合法;

link(x,y);     x和y不能为其本身(1个元素的双向链表);

 交换两元素分为两种情况,两者相邻和不相邻, 

做任何移动之前,要看链表本身是否已符合链表移动后的要求;


#include <map>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#define INF 10000000
//using namespace std;
typedef long long LL;

const int maxn = 100100;
int a[maxn],left[maxn],right[maxn],head;

void link(int x,int y){
right[x]=y; left[y]=x;
}

int n,m;
int main()
{
    int kase=1;
    while(scanf("%d %d",&n,&m)==2){

        for(int i=1;i<=n-1;i++){
            left[i]=i-1; right[i]=i+1;
        }
        left[0]=n;  right[0]=1; left[n]=n-1; right[n]=0;

//        int tt=0;
//        for(int i=0;i<n*3;i++){
//            printf("%d ",tt); tt=right[tt];
//        }
//        printf("\n");
        int order,fff=0,x,y;
        for(int i=0;i<m;i++){
            scanf("%d",&order);
            if(order==4) {fff=!fff; continue;}
            scanf("%d %d",&x,&y);
            
            if(order!=3&&fff) order=3-order;
            if(order==3&&right[y]==x) std::swap(x,y);
            
            int lx=left[x],rx=right[x],ly=left[y],ry=right[y];
            if(order==1){
                if(left[y]==x) continue;
                link(lx,rx);
                link(ly,x);
                link(x,y);
            }
            else if(order==2){
                if(right[y]==x) continue;
                link(lx,rx);
                link(y,x);
                link(x,ry);
            }
            else{
                if(right[x]==y){
                   link(lx,y); link(y,x),link(x,ry);
                }
                else{
                link(lx,y); link(y,rx);
                link(ly,x); link(x,ry);
                }
            }
        }

        LL sum=0,All=(LL)(1+n)*n/2;
        int st=0;
        for(int i=1;i<=n;i++){
            st=right[st];
            if(i&1) sum+=st;
            //std::cout<<st<<" ";
        }
        //std::cout<<"\n";
        if(n%2==0&&fff) sum=All-sum;
        std::cout<<"Case "<<kase++<<": "<<sum<<std::endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值