本文主要是介绍# [USACO3.2] 魔板 Magic Squares,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
[USACO3.2] 魔板 Magic Squares
题目背景
在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有 8 8 8 个大小相同的格子的魔板:
1 2 3 4 1\quad2\quad3\quad4 1234
8 7 6 5 8\quad7\quad6\quad5 8765
题目描述
我们知道魔板的每一个方格都有一种颜色。这 8 8 8 种颜色用前 8 8 8 个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列 { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 } \{1,2,3,4,5,6,7,8\} {1,2,3,4,5,6,7,8} 来表示。这是基本状态。
这里提供三种基本操作,分别用大写字母 A \text A A, B \text B B, C \text C C 来表示(可以通过这些操作改变魔板的状态):
A \text A A:交换上下两行;
B \text B B:将最右边的一列插入最左边;
C \text C C:魔板中央四格作顺时针旋转。
下面是对基本状态进行操作的示范:
A \text A A:
8 7 6 5 8\quad7\quad6\quad5 8765
1 2 3 4 1\quad2\quad3\quad4 1234
B \text B B:
4 1 2 3 4\quad1\quad2\quad3 4123
5 8 7 6 5\quad8\quad7\quad6 5876
C \text C C:
1 7 2 4 1\quad7\quad2\quad4 1724
8 6 3 5 8\quad6\quad3\quad5 8635
对于每种可能的状态,这三种基本操作都可以使用。
你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。
输入格式
只有一行,包括 8 8 8 个整数 a 1 , a 2 ⋯ a 8 ( 1 ≤ a 1 , a 2 ⋯ a 8 ≤ 8 ) a_1,a_2\cdots a_8(1\leq a_1,a_2\cdots a_8\leq8) a1,a2⋯a8(1≤a1,a2⋯a8≤8),用空格分开,不换行,表示目标状态。
输出格式
第一行包括一个整数,表示最短操作序列的长度。
第二行在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出 60 60 60 个字符。
样例 #1
样例输入 #1
2 6 8 4 5 7 3 1
样例输出 #1
7
BCABCCB
提示
题目翻译来自 NOCOW。
USACO Training Section 3.2
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
#include<unordered_map>
using namespace std;
string start1="12345678";
string end1;
unordered_map <string,string> st;
unordered_map <string,int> dist;
queue<string> q;
char **g;
void stc(string ss){int t1=0;for(int i=0;i<4;i++){g[0][i]=ss[t1++];}for(int i=3;i>=0;i--){g[1][i]=ss[t1++];}}string cts(){string s="";for(int i=0;i<4;i++){s.append(1,g[0][i]);}for(int i=3;i>=0;i--){s.append(1,g[1][i]);}return s;
}string operatorA(string ss){stc(ss);for(int i=0;i<4;i++){swap(g[0][i],g[1][i]);}return cts();}
string operatorB(string ss){stc(ss);char a=g[0][3],b=g[1][3];for(int i=3;i>0;i--){g[0][i]=g[0][i-1];g[1][i]=g[1][i-1];}g[0][0]=a;g[1][0]=b;return cts();
}
string operatorC(string ss){stc(ss);char a=g[0][1],b=g[0][2],c=g[1][1];g[1][1]=g[1][2];g[1][2]=b;g[0][2]=a;g[0][1]=c;return cts();
}void bfs(){
st[start1]="";
dist[start1]=0;
q.push(start1);
while(q.size()){auto t=q.front();q.pop();string t1=operatorA(t);string t2=operatorB(t);string t3=operatorC(t);
// cout<<t1<<" 1\n";
// cout<<t2<<" 2\n";
// cout<<t3<<" 3\n";if(!dist.count(t1)){q.push(t1);dist[t1]=dist[t]+1;st[t1]=st[t]+"A";}if(!dist.count(t2)){q.push(t2);dist[t2]=dist[t]+1;st[t2]=st[t]+"B";}if(!dist.count(t3)){q.push(t3);dist[t3]=dist[t]+1;st[t3]=st[t]+"C";}if(dist.count(end1)){return;}}}int main(){
g=new char* [2];
for(int i=0;i<2;i++)*(g+i)=new char[4];for(int i=0;i<8;i++){string s1;cin>>s1;end1+=s1;
}bfs();cout<<dist[end1]<<"\n";
cout<<st[end1];
for(int i=0;i<2;i++)delete[] g[i];}
这篇关于# [USACO3.2] 魔板 Magic Squares的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!