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移动盒子的主要内容,如果未能解决你的问题,请参考以下文章