• C


    You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simulate 4
    kinds of commands:
    • 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y )
    • 2 X Y : move box X to the right to Y (ignore this if X is already the right of Y )
    • 3 X Y : swap box X and Y
    • 4: reverse the whole line.
    Commands are guaranteed to be valid, i.e. X will be not equal to Y .
    For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing
    2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1.
    Then after executing 4, then line becomes 1 3 5 4 6 2

    Input

    There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m
    (1 ≤ n, m ≤ 100, 000). Each of the following m lines contain a command.

    Output

    For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n
    from left to right.

    Sample Input

    6 4
    1 1 4
    2 3 5
    3 1 6
    4
    6 3
    1 1 4
    2 3 5
    3 1 6
    100000 1
    4

    Sample Output

    Case 1: 12
    Case 2: 9
    Case 3: 2500050000

    四种操作,1把x移到y左边,2把x移到y右边,3交换xy,4逆转链表;

    用数组模拟链表,用LEFT和RIGHT两个数组储存每一个数字左右两边的数字是什么

    如果有经过一次4,那个做个标记,后面有操作1,2就要交换,1要变成2,2要变成1,3没影响,对他们的左右连接改动就好了,和链表的操作一样

    吐槽一句,刘汝佳有毒啊,他书上的代码会wa,后面还是自己写出来过的

    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include <iomanip>
    #include<cmath>
    #include<float.h> 
    #include<string.h>
    #include<algorithm>
    #define sf scanf
    #define pf printf
    #define mm(x,b) memset((x),(b),sizeof(x))
    #include<vector>
    #include<queue>
    //#include<map>
    #define rep(i,a,n) for (int i=a;i<n;i++)
    #define per(i,a,n) for (int i=a;i>=n;i--)
    typedef long long ll;
    typedef long double ld;
    typedef double db;
    const ll mod=1e9+100;
    const db e=exp(1);
    using namespace std;
    const double pi=acos(-1.0);
    int n,LEFT[100010],RIGHT[100010];
    void link(int x,int y)
    {
    	LEFT[y]=x;
    	RIGHT[x]=y;
    }
    int main()
    {
    	int m,kase=0;
    	while(sf("%d%d",&n,&m)!=EOF)
    	{
    		rep(i,1,n+1)
    		{
    			LEFT[i]=i-1;
    			RIGHT[i]=(i+1)%(n+1);
    		}
    		RIGHT[0]=1;LEFT[0]=n;
    		int op,x,y,temp=0;
    		while(m--)
    		{
    			sf("%d",&op);
    			if(op==4) temp=!temp;
    			else
    			{
    				sf("%d%d",&x,&y);
    				if(op==3&&RIGHT[y]==x)	swap(x,y);
    				if(op!=3&&temp) op=3-op;
    				int lx=LEFT[x],rx=RIGHT[x],ly=LEFT[y],ry=RIGHT[y];
    				if(op==1)
    				{
    					if(LEFT[y]!=x)
    					{
    						if(RIGHT[y]==x)
    						{
    							link(y,rx);link(ly,x);link(x,y);
    						}else
    						{
    							link(lx,rx);link(x,y);link(ly,x);
    						}
    					}
    				}else if(op==2)
    				{
    					if(RIGHT[y]!=x)
    					{
    						if(LEFT[y]==x)
    						{
    							link(lx,y);link(y,x);link(x,ry);
    						}else
    						{
    							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 if(RIGHT[y]==x)
    					{
    						link(ly,x);link(x,y);link(y,rx);
    					}else
    					{
    						link(lx,y);link(y,rx);link(ly,x);link(x,ry);
    					}
    				}
    			}
    		}
    		int b=0;
    		ll ans=0;
    		rep(i,1,n+1)
    		{
    			b=RIGHT[b];
    			if(i%2==1) ans+=b;
    		}
    		if(temp&&n%2==0) ans=(ll)n*(n+1)/2-ans;
    		pf("Case %d: %lld
    ",++kase,ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    上下文管理
    复习1
    描述符
    迭代器斐波那契数列
    迭代器协议
    __call__ 方法
    析构方法__del__
    __module__和class
    1.8命令执行顺序控制与管道(学习过程)
    1.7文件系统操作与磁盘管理(学习过程)
  • 原文地址:https://www.cnblogs.com/wzl19981116/p/9403886.html
Copyright © 2020-2023  润新知