移动箱子

题目意思是说,给出一个数n,表示存在一个整数序列1……n,然后进行四种操作:

操作一:输入x,y,表示将x移到y的左边(若x本来就在y的左边则忽略);

操作二:输入x,y,表示将x移到y的右边(若x本来就在y的右边则忽略);

操作三:输入x,y,表示交换x和y。

操作四:将整个序列倒置。

最后要求的是操作后的整个序列奇数项的和。

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 <algorithm>
using namespace std;
const int MAX_N=1000;
int lleft[MAX_N],rright[MAX_N];
void link(int L,int R)   //把L和R进行连接 必须L在前R在后
{
    rright[L]=R;lleft[R]=L;
}
int main()
{
    int n,m,x,y,op;
    while(cin>>n>>m)
    {
        for(int i=1;i<=n;i++)
        {
            lleft[i]=i-1;
            rright[i]=(i+1)%(n+1);
        }
        lleft[0]=n;rright[0]=1;
        int inv=0;
        for(int i=1;i<=m;i++)
        {
            cin>>op;
            if(op==4) inv=!inv;   //反转记录
            else
            {
               cin>>x>>y;
               if(op==3 && rright[y]==x) swap(x,y);     //如果a在b的右边
               if(op!=3 && inv) op=3-op;     //如果是在反转后操作
               if(op==1 && x==lleft[y]) continue;//如果x本身就在y的左边
               if(op==2 && x==rright[y]) continue; //如果x本身就在y的右边
               int lx=lleft[x],rx=rright[x],ly=lleft[y],ry=rright[y];
               if(op==1)
               {
                   link(lx,rx);link(ly,x);link(x,y);
               }
               else if(op==2)
               {
                   link(lx,rx);link(y,x);link(x,ry);
               }
               else if(op==3)
               {
                   if(rright[x]==y)
                   {
                       link(lx,y);link(y,x);link(x,ry);
                   }
                   else
                   {
                       link(lx,y);link(y,rx);link(ly,x);link(x,ry);
                   }
               }
            }
            int b=0;
            long long ans=0;
            for(int i=1;i<=n;i++)
            {
                b=rright[b];
                cout << b << endl;
                if(i%2==1) ans+=b;
            }
            if(inv && n%2==0) ans=(long long)n*(n+1)/2-ans;
            cout << ans << endl;
        }


    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值