湖南省赛 B - Boxes in a Line 模拟循环链表

来源:互联网 发布:今年淘宝双11销售额 编辑:程序博客网 时间:2024/05/19 23:17

• 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.



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



题解:

模拟循环链表

起始位置 0 标记起始位置


需要注意相邻的情况




#include<iostream>#include<cstdio>#include<cmath>using namespace std;int Left[100005],Right[100005];void link(int l,int r){    Left[r]=l;    Right[l]=r;}int main(){    int n,m,cases=0;    //freopen("in.txt","r",stdin);    while(~scanf("%d %d",&n,&m))    {        for(int i=1; i<=n; i++)        {            Left[i]=i-1;            Right[i]=i+1;        }        Left[0]=n;        Right[0]=1;        Right[n]=0;        int flag,X,Y,cnt=0;        while(m--)        {            scanf("%d",&flag);            if(flag==4)                cnt=~cnt;            else            {                scanf("%d %d",&X,&Y);                int LX=Left[X],RX=Right[X],LY=Left[Y],RY=Right[Y];                if(flag==3)                {                    if(LX==Y)                    {                        link(LY,X);                        link(X,Y);                        link(Y,RX);                    }                    else if(RX==Y)                    {                        link(LX,Y);                        link(Y,X);                        link(X,RY);                    }                    else                    {                        link(LX,Y);                        link(Y,RX);                        link(LY,X);                        link(X,RY);                    }                    continue;                }                if((flag==1||flag==2)&&cnt)                    flag=3-flag;                if(flag==1)                {                    if(Left[Y]==X)                        continue;                    else                    {                        link(LY,X);                        link(X,Y);                        link(LX,RX);                    }                }                else if(flag==2)                {                    if(Right[Y]==X)                        continue;                    else                    {                        link(LX,RX);                        link(Y,X);                        link(X,RY);                    }                }            }        }        long long sum=0;        int num=0;        for(int i=1; i<=n; i++)        {            num=Right[num];//每个数右边的数            if(i%2)                sum+=num;//判断是否是奇数位上的数        }        if(cnt && n%2==0)            sum=(long long)n*(n+1)/2-sum;        printf("Case %d: %lld\n",++cases,sum);    }    return 0;}


0 0