zoukankan      html  css  js  c++  java
  • UVa 12657

    题意

    你有一行盒子,从左到右依次编号为1, 2, 3,…, n。可以执行以下4种指令:
    1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。
    2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。
    3 X Y表示交换盒子X和Y的位置。
    4 表示反转整条链。

    思路

    双向链表
    每次操作只需修改链表中的元素指向
    另外, 如果程序一直在反转整条链, 如果一直操作的话必然复杂度很高
    因为题目只求所有奇数位置标号之和, 当boxnum为奇数, 盒子逆序无影响
    boxnum为偶数时才有影响, 再具体判断即可 . 所以将反转链操作用bool标记即可

    AC代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    
    using namespace std;
    typedef long long ULL;
    const int maxn = 100000 + 10;
    int l[maxn],r[maxn];
    
    void link( int left, int right ){
        r[left] = right;
        l[right] = left;
    }
    
    int main()
    {
        int boxnum, casenum, i;
        int x, a, b, num = 0;
        ULL result;
        bool ok;
        while( ~scanf("%d%d",&boxnum, &casenum) ){
            for( i = 1; i <= boxnum; i++ ){
                l[i] = i - 1;
                r[i] = ( i + 1 )  % ( boxnum + 1 );
            }
            l[0] = boxnum;
            r[0] = 1;
            ok = false;
            while( casenum-- ){
                scanf("%d",&x);
                if( x == 4 ){   //反转
                    ok = !ok;
                    continue;
                }
                scanf("%d%d",&a,&b);
                if( x == 3 && r[b] == a )   swap(a,b);
                if( x != 3 && ok )  x = 3 - x;
                if( (x == 1 && l[b] == a) || (x == 2 && r[b] == a) )    continue;
                int la = l[a], ra = r[a], lb = l[b], rb = r[b];
                if( x == 1 ){
                    link(la, ra);
                    link(a, b);
                    link(lb, a);
                }
                else if( x == 2 ){
                    link(la, ra);
                    link(b, a);
                    link(a, rb);
                }
                else if( x == 3 ){
                    if( ra == b ){
                        link(la, b);
                        link(b, a);
                        link(a, rb);
                    }
                    else{
                        link(la, b);
                        link(b, ra);
                        link(lb, a);
                        link(a, rb);
                    }
                }
            }
            int t = 0;
            result = 0;
            for( int i = 1; i <= boxnum; i++ ){
                t = r[t];
                if( i % 2 != 0 )    result += t;
            }
            if( ok && boxnum % 2 == 0 )
                result = (ULL)boxnum*(boxnum+1)/2 - result;
            //cout << boxnum*(boxnum+1)/2 ;
            printf("Case %d: %llu
    ",++num, result);
        }
        return 0;
    }
  • 相关阅读:
    多线程-上
    IO流之序列化
    IO流之标准输入输出流
    IO流之BufferedReader/BufferedWriter
    IO流之转换流
    IO流之字符输入输出流
    IO流之字节输入输出流
    JS Flex布局
    MSSQL case when
    钉钉审批流API
  • 原文地址:https://www.cnblogs.com/JinxiSui/p/9740611.html
Copyright © 2011-2022 走看看