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;
    }
  • 相关阅读:
    在WCF中使用Flag Enumerations
    WCF开发教程资源收集
    [转]WCF 4 安全性和 WIF 简介
    Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]
    Asp.Net Web API 2第十八课——Working with Entity Relations in OData
    Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
    Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
    Asp.Net Web API 2第十五课——Model Validation(模型验证)
    函数 生成器 生成器表达式
    函数的进阶
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5789198.html
Copyright © 2011-2022 走看看