首页 > 其他 > 详细

UVA 12657 Boxes in a Line

时间:2019-02-16 12:39:04      阅读:158      评论:0      收藏:0      [点我收藏+]

https://vjudge.net/problem/UVA-12657

题目

你有一行盒子,从左到右依次编号为1, 2, 3,…, n。你可以执行四种指令:

  • 1 X Y表示把盒子X移动到盒子Y左边(如果X已经在Y的左边则忽略此指令)。
  • 2 X Y表示把盒子X移动到盒子Y右边(如果X已经在Y的右边则忽略此指令)。
  • 3 X Y表示交换盒子X和Y的位置。
  • 4 表示反转整条链。

指令保证合法,即X不等于Y。例如,当n=6时在初始状态下执行1 1 4后,盒子序列为2 3 1 4 5 6。接下来执行2 3 5,盒子序列变成2 1 4 5 3 6。再执行3 1 6,得到2 6 4 5 3 1。最终执行4,得到1 3 5 4 6 2。

样例输入

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

 题解

显然要用链表,然后估计等差数列的和上界为最后一项平方,即$ans=O(n^2)$(即使除以2也不影响次数)

那么答案上界是$10^{10}$,爆 int ,所以答案用 long long 存。(样例也好心地提醒了……可是还是没注意)

然后就画图比较……

定义双向链表

技术分享图片

然后1和2操作可以对照图来了……

技术分享图片

如 1 B D, 1 B C

3操作也可以对照图来……

技术分享图片

需要考虑两个是否相邻,验证后发现用这种策略也不会出错……

AC代码

#include<bits/stdc++.h>
using namespace std;

#define REP(i,x,y) for(register int i=x; i<y; i++)
#define REPE(i,x,y) for(register int i=x; i<=y; i++)
#ifdef LOCAL
#define DBG(a,...) printf(a, ##__VA_ARGS__)
#else
#define DBG(a,...) (void)0
#endif

template <class T>
inline void read(T& x) {
    char c=getchar();int f=1;x=0;
    while(!isdigit(c)&&c!=‘-‘)c=getchar();if(c==‘-‘)f=-1,c=getchar();
    while(isdigit(c)){x=x*10+c-‘0‘;c=getchar();}x*=f;
}
template <class T,class... A>void read(T&t,A&...a){read(t);read(a...);}//C++11可用

#define MAXN 100007
int point[MAXN], nxt[MAXN], prv[MAXN];

int main() {
	int n, m;
	int kase=0;
	while(~scanf("%d%d", &n, &m)) {
		kase++;
		bool rev = false;
		REPE(i,1,n) {
			point[i]=i;
			nxt[i]=i+1;
			prv[i]=i-1;
		}
		nxt[n]=-1;
		nxt[0]=1;
		prv[1]=-1;
		prv[0]=n;
		REP(i,0,m) {
			int op; read(op);
			if(op==4) {
				rev = !rev;
//				DBG("%d\n", op);
				continue;
			}
			int *p = rev?nxt:prv;
			int *n = rev?prv:nxt;
			int x,y; read(x,y);
			if(op!=3) {
				int _p=p[x], _n=n[x];
				if(~_p) n[_p]=_n; else n[0]=_n;
				if(~_n) p[_n]=_p; else p[0]=_p;
				_p=p[y], _n=n[y];
				if(op==1) {
					if(~_p) n[_p]=x; else n[0]=x;
					p[x]=_p;
					n[x]=y;
					p[y]=x;
				} else {
					n[y]=x;
					p[x]=y;
					n[x]=_n;
					if(~_n) p[_n]=x; else p[0]=x;
				}
			} else {
				int _p=p[x], _n=n[x], _py=p[y], _ny=n[y];
				if(~_p) n[_p]=y; else n[0]=y;
				if(~_n) p[_n]=y; else p[0]=y;
				if(~_py) n[_py]=x; else n[0]=x;
				if(~_ny) p[_ny]=x; else p[0]=x;
				swap(p[x],p[y]);
				swap(n[x],n[y]);
			}
		}
//		int *p = rev?nxt:prv;
		int *n = rev?prv:nxt;
		long long ans=0;
		for(int i=n[0],j = 1; ~i; i=n[i],j++) {
//			DBG("%d ", i);
			if(j&1) {
				ans+=i;
			}
		}
		printf("Case %d: %lld\n", kase, ans);
	}
	
	return 0;
}

 

比紫书的操作要简单一些(吧)

还是要画图

UVA 12657 Boxes in a Line

原文:https://www.cnblogs.com/sahdsg/p/10387241.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!