题面

Description

在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板:

1 2 3 4

8 7 6 5

我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。

这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):

“A”:交换上下两行;

“B”:将最右边的一列插入最左边;

“C”:魔板中央四格作顺时针旋转。

下面是对基本状态进行操作的示范:

A:

8 7 6 5

1 2 3 4

B:

4 1 2 3

5 8 7 6

C:

1 7 2 4

8 6 3 5

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

Input

只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

Output

Line 1: 包括一个整数,表示最短操作序列的长度。

Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。

Sample Input

2 6 8 4 5 7 3 1

Sample Output

7

BCABCCB

题解

看到题目,很容易就可以想到使用BFS

而状态最多只有8!中,不到50000

完全可以使用数组直接存储

但是我用的是状压(有点麻烦自己。。。。)

然后使用map判重(用康托展开也可以的)

用了STL效率偏低

但是能够AC

其中一定要注意顺序和编号的问题(细节!)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
struct Node
{
int st;//步数
int t;//状态
int ff;//父节点
char way;//方式
}Q[50000];
int h,t;
int End,Beg=12348765;
//bool vis[50000];
map<int,bool> vis;
inline int read()
{
register int x=0,t=1;register char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x;
}
int ten[8]={1,10,100,1000,10000,100000,1000000,10000000};
int change(int tt,int x,int y)//交换状态tt的x位和y位
{
int ttt=tt,a,b;
for(int i=1;i<x;++i)
ttt/=10;
a=ttt%10;
for(int i=x;i<y;++i)
ttt/=10;
b=ttt%10;
return tt-(a-b)*ten[x-1]+(a-b)*ten[y-1];
}
void outp(int t)
{
vector<Node> Ans;
while(t!=1)
{
Ans.push_back(Q[t]);
t=Q[t].ff;
}
int si=Ans.size();
cout<<si<<endl;
for(int i=0;i<si;++i)
{
cout<<Ans[si-i-1].way;
if(i%60==59)cout<<endl;
}
}
int main()
{
for(int i=8;i>=5;--i)
End+=(read()*ten[i-1]);
for(int i=1;i<=4;++i)
End+=(read()*ten[i-1]);
Q[1]=(Node){0,Beg,0,0};
if(Beg==End)//初始时相同
{
printf("0\n");
return 0;
}
vis[Beg]=true;
h=0,t=1;
while(h<t)
{
Node now=Q[++h];
int s;
//变化A
s=now.t;
for(int i=1;i<=4;++i)
s=change(s,i,i+4);//上下交换
if(vis.find(s)==vis.end())//没有访问过
{
vis[s]=true;
Q[++t]=(Node){now.st+1,s,h,'A'};
}
if(s==End)
{
outp(t);
return 0;
}
//变化B
s=now.t;
for(int i=1;i<=3;++i)
s=change(s,i,i+1);
for(int i=5;i<=7;++i)
s=change(s,i,i+1);
if(vis.find(s)==vis.end())
{
vis[s]=true;
Q[++t]=(Node){now.st+1,s,h,'B'};
}
if(s==End)
{
outp(t);
return 0;
}
//变化C
s=now.t;
s=change(s,2,3);
s=change(s,2,7);
s=change(s,2,6);
if(vis.find(s)==vis.end())
{
vis[s]=true;
Q[++t]=(Node){now.st+1,s,h,'C'};
}
if(s==End)
{
outp(t);
return 0;
}
}
return 0;
}

【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板的更多相关文章

  1. 洛谷P2751[USACO]工序安排

    题目传送门 怎么说呢,这个题目我刚开始随便乱搞了几下,交了个暴力代码上去居然还水了49分,数据确实有点弱啊,然后看到洛谷上那位大佬Redbag的题解瞬间就佩服的五体投地,那真的是简洁.易懂又高效.直接 ...

  2. 【洛谷P2722 USACO】 总分 01背包模板

    P2722 总分 Score Inflation 题目背景 学生在我们USACO的竞赛中的得分越多我们越高兴. 我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助 题目描述 我们可以从几个 ...

  3. 洛谷P1474 [USACO 2.3]货币系统 Money Systems [2017年4月计划 动态规划04]

    P1474 货币系统 Money Systems 题目描述 母牛们不但创建了它们自己的政府而且选择了建立了自己的货币系统.由于它们特殊的思考方式,它们对货币的数值感到好奇. 传统地,一个货币系统是由1 ...

  4. BZOJ 1634 洛谷2878 USACO 2007.Jan Protecting the flowers护花

    [题意] 约翰留下他的N只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小 ...

  5. BZOJ 4511 洛谷3131 USACO 16.Jan 七子共

    用sum[i]表示前缀和模7的值,若存在i≤j,满足sum[i]==sum[j],则区间(i,j]的和为7的倍数. O(N)扫出sum[0]~sum[6]第一次出现的位置first和最后一次出现的次数 ...

  6. 洛谷P1353 USACO 跑步 Running

    题目 一道入门的dp,首先要先看懂题目要求. 容易得出状态\(dp[i][j]\)定义为i时间疲劳度为j所得到的最大距离 有两个坑点,首先疲劳到0仍然可以继续疲劳. 有第一个方程: \(dp[i][0 ...

  7. USACO Section 1.3 题解 (洛谷OJ P1209 P1444 P3650 P2693)

    usaco ch1.4 sort(d , d + c, [](int a, int b) -> bool { return a > b; }); 生成与过滤 generator&& ...

  8. 洛谷 USACO P2207 Photo

    P2207 Photo 题目描述 Framer Jhon 打算给他的N头奶牛照相,( 2 <= N <= 1 000 000 000) . 他们排成一条线,并且依次取1~N作为编号. 每一 ...

  9. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

随机推荐

  1. linear-grident的属性和使用

    css3新增Gradient属性,用来增加渐变的效果,渐变分为线性渐变 linear-grident 和 径向渐变 radial-grident,这篇文章主要介绍线性渐变linear-grident ...

  2. shell脚本实现nfs服务安装配置,共享文件分发

    ##############################Deploy nfs######################## echo "start deploy nfs-server& ...

  3. yum安装man命令程序错误

    第一次安装CentOS后,man命令无法使用,查了一下,发现没有安装man命令程序.尝试安装man yum install man 结果如下: Loaded plugins: fastestmirro ...

  4. C#获取文件夹下的所有文件的文件名(转载)

    String path = @"X:\xxx\xxx";   //第一种方法 var files = Directory.GetFiles(path, "*.txt&qu ...

  5. 剑指offer第三天

    21.栈的压入.弹出序列 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3, ...

  6. POJ - 3268 单源最短路

    题意:给定一些有向边,以及一个目的地,从某个点到达目的地,再从目的地回到那个点.共有n个点,问这n个点花费最大是多少? 思路:从目的地回去直接把目的地作为源点即可.那么从某个点到达目的地应该如何得到最 ...

  7. 算法提高 金属采集 树形DP

    题目链接:金属采集 思路:d(i, j)表示在以i为根结点的子树中使用j个机器人的最小花费.设v为u的一个子节点,从节点i使用k个机器人收集以v为根结点的能量,状态转移方程为d(u, i) = min ...

  8. 在SpringBoot中使用FluentValidator验证插件

    前言 在我们编写项目的时候,在controller中往往离不开对一些数据的校验.这里并不是说对于这些数据业务上面的校验,而是对这些数据进行空校验或者是长度校验等. 有些时候校验可以省略,根据业务的需要 ...

  9. Wireshark抓包常见出现错误

    转自这里 1.   tcp out-of-order(tcp有问题) 解答: 1).    应该有很多原因.但是多半是网络拥塞,导致顺序包抵达时间不同,延时太长,或者包丢失,需要重新组合数据单元 因为 ...

  10. 错误:readline/readline.h:没有那个文件或目录解决方法

    curl -R -O http://www.lua.org/ftp/lua-5.3.0.tar.gz tar zxf lua-5.3.0.tar.gz cd lua-5.3.0 make linux ...