UVA 12657 Boxes in a Line
Posted sahdsg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 12657 Boxes in a Line相关的知识,希望对你有一定的参考价值。
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 ", 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 ", kase, ans); } return 0; }
比紫书的操作要简单一些(吧)
还是要画图
以上是关于UVA 12657 Boxes in a Line的主要内容,如果未能解决你的问题,请参考以下文章
Uva 12657 Boxes in a Line 双向链表
Boxes in a Line UVA - 12657 (双向链表)