【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
来源:互联网 发布:云计算开发语言 编辑:程序博客网 时间:2024/06/03 19:40
题面
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】魔板
- 【USACO题库】3.2.5 Magic Squares魔板
- USACO 3.2.5
- USACO/msquare 3.2.5
- usaco 3.2.5 msquare
- USACO 3.2 Magic Squares 魔板
- USACO 3.2.5 magic square
- USACO 3.2.5 Magic Squares
- 【USACO题库】3.2.5 Magic Squares魔板(广搜)
- JZOJ1286.【USACO题库】3.2.5 Magic Squares魔板
- 1286. 【USACO题库】3.2.5 Magic Squares魔板 (Standard IO)
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO 3.2 Magic Squares 魔板 (BFS-HASH)
- USACO Training Section 3.2 & 洛谷P2730
- USACO 3.2 Factorials
- USACO 3.2 分析
- USACO 3.2.2 stringsobits
- 驱动调试技术
- Bitmap_多级缓存实现图片加载
- 自己写的数字最大最小值numvalue-check指令
- CentOS 官网下载及版本说明
- 关于eclipse的mysql连接配置
- 【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
- C/C++学习之basic_string
- 插入排序-算法
- LeetCode--Regular Expression Matching
- NP-complete problems课后题
- rpm 安装软件
- 从Hermite插值公式推导Smoothstep插值公式
- PAT b1046-b1049题解
- 【网络】URG 和 PSH 标志位