BZOJ4072[Wf2014] baggage

原题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4072

baggage

Description

给定一排长度为4n的格子,编号从-2n+1到2n。

每个编号为正的格子中有一个物品,其中每个编号为奇数的格子中有一个B类物品,编号为偶数的格子中有一个A类物品。

例如:当n=4时初始状态如下图所示:

附图.png

你只能进行一种操作:选择某两个相邻的格子,要求这两个格子中都有物品,然后移动到另外两个相邻的空格子中,不能改变两个格子的相对位置。

要求进行最少的操作使得所有物品以AAA…ABBB…B(n个A和n个B)的形式排列在一起。

Input

输入数据包含一行一个正整数n,含义如题面中所示

Output

输出一个最短的满足要求的移动序列。

每个操作的格式如下:
x to y

含义为将x和x+1两个格子中的物品移动到y和y+1两个位置。

如果有多组方案可以达到要求,你可以输出任意一组。

Sample Input

5

Sample Output

8 to -1
3 to 8
6 to 3
0 to 6
9 to 0

题解

先运用人类的智慧,手动处理 37 3 ∼ 7 的解,设 (BA) ( B A ) 表示若干个 BA B A 摆放成的形如 BABABABA B A B A B A ⋯ B A 的序列; (AB) ( A B ) 表示左半边为 A A ,右半边为B的形如 AAAABBBB A A A ⋯ A B ⋯ B B B 的序列,发现除了 n=3 n = 3 的情况,其他情况的变化是有规律的:

_ _(BA)(AB)_ _ _   _ ( B A ) → ( A B ) _   _

意思说, 47 4 ∼ 7 的变化都只会用到最左边的两个多余的空格子,其他空格子都不会用。

再考虑 n>7 n > 7 的情况,我们可以做这样的变换:

_ _BABA(BA)BABAABBABA(BA)B_ _AABBA_ _(BA)BBAA _   _ B A B A ( B A ) B A B A A B B A B A ( B A ) B _   _ A A B B A _   _ ( B A ) B B A A

这样,我们就留出了中间的序列从 (BA) ( B A ) 变到 (AB) ( A B ) 的两个格子,然后我们就可以递归下去,把中间的序列变成 (AB)_ _ ( A B ) _   _ ,再接着改最外面的:

ABBA(AB)_ _BBAAA_ _A(AB)BBBBAAAAAA(AB)BBBB_ _ A B B A ( A B ) _   _ B B A A A _   _ A ( A B ) B B B B A A A A A A ( A B ) B B B B _   _

这样我们就成功将整个序列合并成了 (AB) ( A B )

代码
#include <bits/stdc++.h>
#define p(x,y) printf("%d to %d\n",x,y)
int n;
void in(){scanf("%d",&n);}
void ac(int l,int r){
    if(r-l+1==6){p(2,-1),p(5,2),p(3,-3);return;}
    if(r-l+1==8){p(l+5,l-2),p(l+2,l+5),p(l-1,l+2),p(l+6,l-1);return;}
    if(r-l+1==10){p(l+7,l-2),p(l+2,l+7),p(l+5,l+2),p(l-1,l+5),p(l+8,l-1);return;}
    if(r-l+1==12){p(l+9,l-2),p(l+6,l+9),p(l+1,l+6),p(l+5,l+1),p(l-1,l+5),p(l+10,l-1);return;}
    if(r-l+1==14){p(l+7,l-2),p(l+4,l+7),p(l+11,l+4),p(l+2,l+11),p(l+8,l+2),p(l-1,l+8),p(l+12,l-1);return;}
    p(r-2,l-2),p(l+2,r-2);ac(l+4,r-4);p(l-1,r-5),p(r-1,l-1);
}
int main(){in();ac(1,n<<1);}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值