Uva移动盒子

Posted karshey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Uva移动盒子相关的知识,希望对你有一定的参考价值。

在这里插入图片描述
输入:

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

输出:

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

总结: 通过对比自己不断WA的代码发现:
1、Link函数是连接左右两点的。
2、万能头里有right、left的命名。
3、要注意反转,反转后的1、2操作其实方向会变,可以举例感受。
4、若反转了且n为偶数,其实取的是另一半;为奇数则不变。可举例感受。

代码:例题6-5 移动盒子 UVa 12657 链表(模拟链表)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cstdlib>
 
using namespace std;
const int maxn=100005;
int Right[100005],Left[100005];
 
void link(int L, int R)//连接两个点
{
    Right[L]=R;
    Left[R]=L;
}
 
int main()
{
    int n,m;
    int op;
    int cas=0;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1; i<=n; i++)
        {
            Left[i]=i-1;
            Right[i]=(i+1)%(n+1);
        }
        Right[0]=1;//形成循环
        Left[0]=n;
 
        int inv=0;
        int X,Y;
        while(m--)
        {
            cin>>op;
            if(op==4)//先判是否反转
                inv=!inv;
            else
            {
                cin>>X>>Y;
                if(op==3&&Right[Y]==X)  swap(X,Y);
                if(op!=3&&inv)  op=3-op;//若反转了,1 2操作要反过来
                if(op==1&&Right[X]==Y)  continue;
                if(op==2&&Right[Y]==X)  continue;
 
                int LX=Left[X], RX=Right[X], LY=Left[Y], RY=Right[Y];
                if(op==1)
                {
                    link(LX,RX);
                    link(X,Y);
                    link(LY,X);
                }
                else if(op==2)
                {
                    link(LX,RX);
                    link(Y,X);
                    link(X,RY);
                }
                else if(op==3)
                {
                    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);
                    }
                }
            }
        }
        int t=0;
        long long ans=0;
        for(int i=1; i<=n; i++)
        {
            t=Right[t];
            if(i%2)
                ans+=t;
        }
        if(inv&&n%2==0) ans=(long long)n*(n+1)/2-ans;//如果反转且为偶数,要的正好是另一边;为奇数不会发生变化。
        cout<<"Case "<<++cas<<": "<<ans<<endl;
    }
 
    return 0;
}

以上是关于Uva移动盒子的主要内容,如果未能解决你的问题,请参考以下文章

Uva 12657 移动盒子(双向链表)

Uva12657 (Boxes in a Line)移动盒子

UVA 12657 Boxes in a Line

算法入门经典第六章 例题6-5 移动盒子

Uva1639(概率期望/对数处理避免丢失精度)

uva10648 概率dp