zoukankan      html  css  js  c++  java
  • UVA 12657 Boxes in a Line 双向链表

    题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=47066

    利用链表换位置时间复杂度为1的优越性,同时也考虑到使用实际的链表对一个数字进行定位需要扫一遍,时间复杂度难以承受,因此使用数组模拟双向链表。

    易错点:1.要对特殊位置进行处理,例如xy相邻的情况

               2.注意链表头和尾可能在任意一个操作中变化,要进行检查

    #include <bits/stdc++.h>
    using namespace std;
    const int Max=1e5+10;
    typedef long long LL;
    #define scan(x) scanf("%d",&x);
    struct node
    {
        int data,p[2];
    }lists[Max];
    int n,m,head,tail,swi;      //!swi--left,swi--right
    int lm,rm;
    int Scan()
    {
        int res=0,ch,flag=0;
        if((ch=getchar())=='-')
            flag=1;
        else if(ch>='0'&&ch<='9')
            res=ch-'0';
        while((ch=getchar())>='0'&&ch<='9')
            res=res*10+ch-'0';
        return flag?-res:res;
    }
    inline void index(int x,int &x1,int &x2,int &x3)
    {
        x2=x;
        x1=lists[x2].p[!swi];
        x3=lists[x2].p[swi];
    }
    void check(int x)
    {
        if(x<1||x>n) return;
        if(lists[x].p[!swi]==lm)  head=x;
        if(lists[x].p[swi]==rm) tail=x;
    }
    void movesl(int x,int y)
    {
        int x1,x2,x3,y1,y2,y3;
        index(x,x1,x2,x3);index(y,y1,y2,y3);
        if(x1==y2) return;
        lists[y3].p[!swi]=y1;
    
        lists[y1].p[swi]=y3;
        lists[y2].p[!swi]=x1;lists[x1].p[swi]=y2;
        lists[y2].p[swi]=x2;lists[x2].p[!swi]=y2;
        check(y1);check(x1);check(x3);check(x2);check(y2);check(y3);
    }
    void movesr(int x,int y)
    {
        int x1,x2,x3,y1,y2,y3;
        index(x,x1,x2,x3);index(y,y1,y2,y3);
        if(x3==y2) return;
        lists[y3].p[!swi]=y1;
        lists[y1].p[swi]=y3;
        lists[y2].p[!swi]=x2;lists[x2].p[swi]=y2;
        lists[y2].p[swi]=x3;lists[x3].p[!swi]=y2;
        check(y1);check(x1);check(x3);check(x2);check(y2);check(y3);
    }
    void swaps1(int x1,int x,int y,int y1)
    {
        lists[x].p[!swi]=y;
        lists[x].p[swi]=y1;
        lists[y].p[!swi]=x1;
        lists[y].p[swi]=x;
        lists[x1].p[swi]=y;
        lists[y1].p[!swi]=x;
        check(x1);check(x);check(y);check(y1);
    }
    void swaps(int x,int y)
    {
        int x1,x2,x3,y1,y2,y3;
        index(x,x1,x2,x3);index(y,y1,y2,y3);
        if(x3==y2) {swaps1(x1,x2,y2,y3);return;}
        if(y3==x2) {swaps1(y1,y2,x2,x3);return;}
        lists[x2].p[!swi]=y1;lists[x2].p[swi]=y3;
        lists[x1].p[swi]=y2;lists[x3].p[!swi]=y2;
        lists[y1].p[swi]=x2;lists[y3].p[!swi]=x2;
        lists[y2].p[!swi]=x1;lists[y2].p[swi]=x3;
        check(x2);check(y2);
    }
    void reverses()
    {
        swap(head,tail);
        swi=!swi;
        swap(lm,rm);
    }
    LL cacu()
    {
        int g=0;
        LL ans=0;
        for(int i=head;g<n&&i>=1&&i<=n;i=lists[i].p[swi])
        {
    
            g++;
            if(g%2)
            {
                ans+=i;
            }
        }
        return ans;
    }
    void open()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    int main()
    {
      //  open();
        int T=0;
        while(~scanf("%d%d",&n,&m))
        {
            swi=1;
            int x;
            memset(lists,0,sizeof(lists));
            for(int i=1; i<=n; i++)
            {
                lists[i].data=i;
                lists[i].p[!swi]=i-1;
                lists[i].p[swi]=i+1;
            }
            head=1;tail=n;lm=0;rm=n+1;
            int op,y;
            for(int i=1; i<=m; i++)
            {
                op=Scan();
                if(op!=4)
                {
                  x=Scan();y=Scan();
                  if(x<1||x>n||y<1||y>n) continue;
                  if(x==y) continue;
                }
                switch(op)
                {
                case 1:
                    movesl(y,x);
                    break;
                case 2:
                    movesr(y,x);
                    break;
                case 3:
                    swaps(x,y);
                    break;
                case 4:
                    reverses();break;
                }
            }
            LL ans=0,ans1;
            ans=cacu();
           printf("Case %d: %lld
    ",++T,ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    [linux]Linux下的log
    [WDT]内部看门狗和外部看门狗
    [misc]printf/fprintf/sprintf/snprintf函数
    [Linux]read/write和fread/fwrite有什么区别
    移动端图片操作(二)——预览、旋转、合成
    移动端图片操作(一)——上传
    实现tap的多种方式
    Hammer.js分析(四)——recognizer.js
    Hammer.js分析(三)——input.js
    Hammer.js分析(二)——manager.js
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5676404.html
Copyright © 2011-2022 走看看