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\n",++T,ans);
    }
    return 0;
}
View Code

 

posted @ 2016-07-16 15:04  江南何采莲  阅读(165)  评论(0编辑  收藏  举报