12657 Boxes in a Line

#include

using namespace std;

 

const int MAX=100010;

int RIGHT[MAX];

int LEFT[MAX];

 

void link(int l,int r);

 

int main()

{

   int n,m;

   int kase=1;

   while(cin>>n>>m)

    {

       for(int i=1;i<=n;i++)

       {

           LEFT[i]=i-1;

           RIGHT[i]=(i+1)%(n+1);

       }

       LEFT[0]=n;

       RIGHT[0]=1;

 

       int op,x,y;

       bool flag=false;

       while(m--)

       {

           cin>>op;

 

           if(op==4)

           {

                flag=!flag;

           }

           else

           {

                cin>>x>>y;

                int lx=LEFT[x],rx=RIGHT[x];

                int ly=LEFT[y],ry=RIGHT[y];

                if(op!=3&&flag)

                {

                    op=3-op;

                }

                if(op==1&&x==LEFT[y])

                {

                    continue;

                }

                if(op==2&&x==RIGHT[y])

                {

                    continue;

                }

 

                if(op==1)

                {

                    link(lx,rx);

                    link(ly,x);

                    link(x,y);

                }

                if(op==2)

                {

                    link(lx,rx);

                    link(y,x);

                    link(x,ry);

                }

                if(op==3)

                {

                    if(x==LEFT[y])

                    {

                        link(lx,y);

                        link(y,x);

                        link(x,ry);

                    }

                   else if(x==RIGHT[y])

                    {

                        link(ly,x);

                        link(x,y);

                        link(y,rx);

                    }

                    else

                    {

                        link(lx,y);

                        link(y,rx);

                        link(ly,x);

                        link(x,ry);

                    }

                }

           }

       }

 

       int a=0;

       long long  ans=0;

       for(int i=1;i<=n;i++)

       {

           a=RIGHT[a];

           if(i%2==1)

           {

                ans=ans+a;

           }

       }

       if(flag&&n%2==0)

       {

           ans=(long long)(n/2)*(n+1)-ans;

       }

 

       cout<<"Case "<

       kase++;

    }

}

 

void link(int l,int r)

{

   RIGHT[l]=r;

   LEFT[r]=l;

}

解析:

采用双向链表,用left[i]与right[i]分别存储标号为i的盒子左边和右边的盒子的标号(如果是0,则表示不存在),link函数使得两的个盒子互相连接。操作4比较特殊,为了避免一次性修改所有元素的指针,增加一个布尔变量flag来标志当前的编号是否被转置。true表示被转置,反之没被转置。当op为1,2且flag=true时,只需要把op变为3-op(互相等价的),操作3不受4的影响。输出要根据盒子总数的奇偶性和flag的真假来调整。

你可能感兴趣的:(12657 Boxes in a Line)