• 紫书题目移动盒子


    题目的意思是,你有一行的盒子,這邪恶盒子是按照序号1-n的顺序进行排列的,现在你要做的就是,在给你一个n和一个m的时候,其中的n是指由多少个盒子在排列,m是指要执行多少次的操作,这里一共有4中操作,其中一是,输入1 1 2就是执行第一次操作,如果1实在2的左边这不用进行操作,如果1在2的右边那么就要把1放到2的左边,同样的2号的操作就是输入2 2 3,意思是进行2操作,如果2在3 的右边就不用进行操作,如果2在3的左边就要把2移动到3的右边,还有就是3号操作,直接将输入的两个数进行互相交换。至于4操作就是将这一列的数字首位倒置。

     
    变动一个数子的话只会涉及到整个数字左右的两个数字,所以的话就要两个标记来进行变动。这里设置了两个数组来表示这两个标记。4种操作中的第四个可以不用进行任何的动作,只需要进行一次标记就可以完成第四个操作了,所以这里可以设置一个标记,每次进行操作的时候通过判断这个标记是否存在来进行操作,比如如果这个标记是存在的,那么进行第一个操作的时候就变成了进行第二个操作了,而第三个操作就可以不用进行了。同时书上的源程序有很多值得学习的地方,例如在输入标记的数组right的时候,使用的是right[i]=(i+1)%(n+1);这样的好处就是可以防止数据的输入越界。还有就是在写程序的时候要注意的是每一部分要规范的进行书写,让人感觉层次分明。还有很巧妙的一点就是在最后的时候当标记标记显示是执行过4号操作的时候,要计算相反的序号地和,书中是通过计算前n项的和减去计算出来的奇数项。
    源代码:
    #include<cstdio>
    #include<cstring>
    const int maxn=100000+10;
    int n,left[maxn],right[maxn];
    void link(int L,int R)
    {
        right[L]=R;
        left[R]=L;
    }
    void swap(int &x,int &y)
    {
        int a;
        a=x;
        x=y;
        y=a;
    }
    int main()
    {
        int m,kase=0;
        while(scanf("%d%d",&n,&m)==2)
        {
            for(int i=1;i<=n;i++)
            {
                left[i]=i-1;
                right[i]=(i+1)%(n+1);
            }
            right[0]=1;
            left[0]=n;
     
            int op,X,Y,inv=0;
            while(m--)
            {
                scanf("%d",&op);
                if(op==4)inv=!inv;
                else
                {
                    scanf("%d%d",&X,&Y);
                    if(op==3&&right[Y]==X) swap(X,Y);
                    if(op!=3&&inv)op=3-op;
                    if(op==1&&X==left[Y])continue;
                    if(op==2&&Y==right[X])continue;
     
                    int LX=left[X],RX=right[X],LY=left[Y],RY=right[Y];
                    if(op==1)
                    {
                        link(LX,RX);
                        link(LY,X);
                        link(X,Y);
                    }
                    else if(op==2)
                    {
                        link(LX,RX);
                        link(Y,X);
                        link(X,RY);
                    }
                    else if(op==3)
                    {
                        if(right[X]==Y)
                        {
                            link(LX,Y);
                            link(Y,X);
                            link(X,RY);
                        }
                        else
                        {
                            link(LX,Y);
                            link(Y,RX);
                            link(LY,X);
                            link(X,RY);
                        }
                    }
                }
            }
     
            int b=0;
            long long ans=0;
            for(int i=1;i<=n;i++)
            {
                b=right[b];
                if(i%2==1)
                    ans+=b;
            }
            if(inv&&n%2==0)
                ans=(long long)n*(n+1)/2-ans;
            printf("Case %d: %lld\n",++kase,ans);
        }
        return 0;
    }
  • 相关阅读:
    FCKeditor的问题
    每天学习一点点(2010年二月)
    Excel使用小技巧
    JavaScript 取页面属性
    附加 数据库错误 5120
    CSS中元素水平居中显示的方法
    css中height:100%不起作用的解决方法
    SQL SERVER数据库开发之存储过程应用(转载)
    双路由器双小型交换机组建公司网络,2个公网IP上网案例(转载)
    如何解决VS2005没有代码智能提示(联想)的问题(转载)
  • 原文地址:https://www.cnblogs.com/yewa/p/7243534.html
Copyright © 2020-2023  润新知