【CJOJ1372】【洛谷2730】【USACO 3.2.5】魔板
2017-07-17 20:03
369 查看
题面
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 1Sample Output
7BCABCCB
题解
看到题目,很容易就可以想到使用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】魔板
- 【USACO3.2.5】魔板 康托展开/BFS
- 洛谷 2730 SSL 1692 魔板
- 洛谷 P2925 [USACO08DEC]干草出售Hay For Sale
- USACO 3.2.5 magic square
- 洛谷2846 USACO08NOV 光开关 Light Switching
- 【洛谷】【USACO】P1118 数字三角形
- 洛谷 1948 [USACO08JAN]电话线Telephone Lines
- 洛谷——P2984 [USACO10FEB]给巧克力Chocolate Giving
- 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication(最小割)
- 【DP】+【贪心】【前缀和】洛谷P2893 [USACO08FEB]修路Making the Grade 题解
- 洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm
- 洛谷P3052 [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper
- AC自动机-洛谷3121 [USACO15FEB]审查(黄金)Censoring (Gold)
- 洛谷 [USACO1.1]黑色星期五Friday the Thirteenth
- POJ1274 The Perfect Stall_洛谷P1894 [USACO4.2]完美的牛栏
- 洛谷 2210 [USACO] Haywire dfs+剪枝
- 洛谷 P2915 [USACO08NOV]奶牛混合起来Mixed Up Cows
- [USACO16OPEN]关闭农场Closing the Farm(洛谷 3144)