zoukankan      html  css  js  c++  java
  • UVA 12657 Boxes in a Line(双向链表+小技巧)

    题意:对于一行按照顺序排列盒子数字与位置都为 1,2,3,4....n

    执行四种操作

    c = 1    x 放到 y 的左边

    c =2     x 放到 y 的右边

    c =3   交换 x, y

    c =4   颠倒链

    最后求出奇数位置的数的总和

    题解:直接维护无论如何每次每次都需要维护一段区间的位置,因此不去看位置、只需要知道每个盒子左边是哪个盒子右边是哪个盒子

       这样就直接使用双向链表维护,接着颠倒时注意只是标记就好

       最后注意几个细节:

        首先颠倒后1与2的交换需要互换;

        维护链表时可以提取出一个函数,每次都只需要多次使用这个函数;

        c等于1,2,3时x与y的位置相邻时会出现很大的问题

    #include<set>
    #include<map>
    #include<queue>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<iomanip>
    #include<stdlib.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define eps 1E-8
    /*注意可能会有输出-0.000*/
    #define sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
    #define cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
    #define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
    #define mul(a,b) (a<<b)
    #define dir(a,b) (a>>b)
    typedef long long ll;
    typedef unsigned long long ull;
    const int Inf=1<<28;
    const ll INF=1LL<<60;
    const double Pi=acos(-1.0);
    const int Mod=1e9+7;
    const int Max=100010;
    struct node
    {
        int left,right;
    } ball[Max];//**表示i这个数字左右两边的数字**
    void initPosition(int n)//双向链表初始化
    {
        for(int i=1; i<=n; ++i)
        {
            ball[i].left=i-1;
            ball[i].right=(i+1)%(n+1);
        }
    }
    void link(int l,int r)//左右相互连接
    {
        ball[l].right=r;
        ball[r].left=l;
    }
    inline void Solve(int type,int &mark)
    {
        if(type==4)
        {
            mark=(mark^1);
            return;
        }
        if(type!=3&&!mark)
            type=3-type;//注意反转后只需交换type的1与2就好
        int x,y;
        scanf("%d %d",&x,&y);
        int Lx=ball[x].left;
        int Rx=ball[x].right;
        int Ly=ball[y].left;
        int Ry=ball[y].right;
        if(type==1&&Rx==y||type==2&&Lx==y)
            return;
        if(type==1)//通过下标找到x、y,将x放在y的左边
        {
            link(Lx,Rx);//**找到6个交换的规律**
            link(Ly,x);
            link(x,y);
        }
        else if(type==2)
        {
            link(Lx,Rx);
            link(x,Ry);
            link(y,x);
        }
        else if(type==3)
        {
            if(Rx==y)//注意
            {
                link(Lx,y);
                link(y,x);
                link(x,Ry);
            }
            else if(Lx==y){
                link(y,Rx);
                link(Ly,x);
                link(x,y);
            }
            else
            {
                link(y,Rx);
                link(Ly,x);
                link(Lx,y);
                link(x,Ry);
            }
        }
    }
    ll Print(int n,int mark)
    {
        ll res=0LL;
        int start=0;
        for(int i=1; i<=n; ++i)
        {
            if(ball[i].left==0)
            {
                start=i;
                break;
            }
        }
        int now=start;
        int coun=0;
        while(now)
        {
            res+=now;
            now=ball[now].right;
            if(now)
                now=ball[now].right;
        }
        if(!(n&1)&&!mark)
            res=(ll)n*(n+1)/2-res;
        return res;
    }
    int main()
    {
        int n,m;
        int coun=0;
        while(~scanf("%d %d",&n,&m))
        {
            initPosition(n);
            int mark=1;//标记是否反转
            while(m--)
            {
                int type;
                scanf("%d",&type);
                Solve(type,mark);
            }
            printf("Case %d: %lld
    ",++coun,Print(n,mark));
        }
        return 0;
    }
  • 相关阅读:
    《java网络编程》
    画类图的使用工具----转载
    桌面应用要素
    java桌面应用
    java网络程序
    网络程序
    java中的数据类型
    数据类型要素
    java中的设计模式
    输入一个年龄,判断年龄范围
  • 原文地址:https://www.cnblogs.com/zhuanzhuruyi/p/6741230.html
Copyright © 2011-2022 走看看