码迷,mamicode.com
首页 > 其他好文 > 详细

csu 1329 一行盒子(链表操作)

时间:2016-08-19 23:51:56      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

1329: 一行盒子

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 693  Solved: 134
[Submit][Status][Web Board]

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 41 1 42 3 53 1 646 31 1 42 3 53 1 6100000 14

Sample Output

Case 1: 12Case 2: 9Case 3: 2500050000

第一次做这类型的题,真的有蛮坑的,特别是SAWP操作,情况漏考虑就是死循环,唉,做个模板用吧。。。这题两点要注意,一是我们只要在逻辑上面进行翻转
即可,如果是奇数次,那么只要将1操作看成2操作,2操作看成1操作即可。然后最后输出的时候也只要奇数次翻转就从尾部开始算,偶数次就从头部开始算。
swap(x,y)一定要考虑 next[x] = y和next[y] = x两种情况。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 200005;
int n,m;
int chi[maxn],pre[maxn];

void init()
{
    pre[1] = 0;
    for(int i = 2; i <= n; i++)
        pre[i] = i - 1;
    for(int i = n-1; i >= 1; i--)
        chi[i] = i + 1;
    chi[n] = 0;
}
void left(int x,int y){ ///将x 移到y的左边
     if(pre[y]==x) return;
     int p = pre[x]; //x的父亲节点
     pre[chi[x]] = p,chi[p] = chi[x];
     p = pre[y],chi[p] = x;
     pre[x] = p,chi[x] = y,pre[y] = x;
}
void right(int x,int y){ ///将x移向y的右边
     if(chi[y]==x) return;
     int p = pre[x]; //x的父亲节点
     pre[chi[x]] = p,chi[p] = chi[x];
     pre[x] = y,chi[x] = chi[y];
     pre[chi[y]] = x,chi[y] = x;
}
void Swap(int x,int y){ ///链表的交换操作
    int p1 = pre[x],p2 = pre[y];
    int c1 = chi[x],c2 = chi[y];
    if(chi[x]==y){
        chi[p1]=y,chi[y]=x,chi[x]=c2;
        pre[c2]=x,pre[x]=y,pre[y]=p1;
    }else if(chi[y]==x){
        chi[p2]=x,chi[x]=y,chi[y]=c1;
        pre[c1]=y,pre[y]=x,pre[x]=p2;
    }else{
        chi[p1] = y,pre[y] = p1;
        chi[y] = c1,pre[c1] = y;
        chi[p2] = x,chi[x] = c2;
        pre[c2] = x,pre[x] = p2;
    }
}
int main()
{
    //freopen("b.in","r",stdin);
    //freopen("b.txt","w",stdout);
    int op,x,y;
    int cnt = 0,cas=1;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        init();
        cnt = 0;
        while(m--)
        {
            scanf("%d",&op);
            if(op==4) cnt++;
            else
            {
                if(op<3&&cnt%2==1) op = 3-op;
                if(op == 1)
                {
                    scanf("%d %d",&x,&y);
                    left(x,y);
                }
                else if(op == 2)
                {
                    scanf("%d %d",&x,&y);
                    right(x,y);
                }
                else if(op == 3)
                {
                    scanf("%d %d",&x,&y);
                    Swap(x,y);
                }
            }

        }
        long long ans = 0;
        if(cnt % 2 == 1) //翻转了
        {
            int head;
            for(int i = 1; i <= n; i++)
                if(chi[i] ==0)
                {
                    head = i;
                    break;
                }
            int f = 1;
            while(pre[head] != 0)
            {
                if(f%2==1) ans+=head;
                head = pre[head];
                f++;
            }
            if(f%2==1) ans+=head;
        }
        else
        {
            int head;
            for(int i = 1; i <= n; i++)
                if(pre[i] == 0)
                {
                    head = i;
                    break;
                }
            int f = 1;
            while(chi[head] !=0)
            {
                if(f%2==1) ans+=head;
                head = chi[head];
                f++;
            }
            if(f%2==1) ans+=head;
        }
        printf("Case %d: %I64d\n",cas++,ans);
    }
    return 0;
}

 

csu 1329 一行盒子(链表操作)

标签:

原文地址:http://www.cnblogs.com/liyinggang/p/5789198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!