zoukankan      html  css  js  c++  java
  • csu 1329 一行盒子(链表操作)

    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
    ",cas++,ans);
        }
        return 0;
    }
  • 相关阅读:
    28,intellij idea工程包含scala代码这样打包
    1、调侃程序员
    2 20个常用正则表达式
    27 Java动态加载第三方jar包中的类
    26 查看文件内容有多少行?
    25 读取jar包内log4j.properties文件方法
    MySQL表类型
    Hibernate-检索策略
    Hibernate-Native SQL
    Hibernate-Criteria Queries
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5789198.html
Copyright © 2011-2022 走看看