水题一条,但可以通过此题学习宽搜或深搜,然后通过和1151的比较,学习搜索中剪枝的作用。
宽搜中可以在递归的一开始就先检测是否搜到目标值(如下面贴上来的代码),也可以在将候选节点入队时检查。但如果是在入队时检查的话记得要注意在初始节点入队时检查初始节点是否就已经是目标值。
一开始犯的错误就是红色字体标出的错误。因此自己写多几个测试用例测试自己的代码,全部测试用例如下:
4
5 8 7 6
4 1 2 3
3
8 7 6 5
1 2 3 4
0
1 2 3 4
8 7 6 5
1
1 7 2 4
8 6 3 5
2
1 6 7 4
8 3 2 5
1
1 6 7 4
8 3 2 5
-1
2 AB
1 A
0 // 边界测试
1 C // 边界测试
2 CC // 边界测试
以下为代码:
#include <iostream>
#include <queue>
using namespace std;
struct Node{
int a;
string path;
};
int toSingleNum(int a[]) {
int i;
int n = 0;
int pow = 1;
for( i = 7; i >= 0; i-- ) {
n+=a[i]*pow;
pow*=10;
}
return n;
}
int A(int a) {
int m = a/10000;
int n = a%10000;
return n*10000 + m;
}
int B( int a) {
int n3 = a/100000; // 123
int n4 = a/10000; // 1234
int n44 = n4-n3*10; // 4
int n88 = a%10; // 5
int n58 = a%10000; // 8765
int n57 = (n58 - n88)/10; // 876
return int(n44*1e7 + n3*1e4 + n88 * 1e3 + n57);
}
int C( int c) {
int i, temp;
int a[8];
int pow = int(1e7);
for( i = 0; i < 8; i++ ) {
a[i] = c/pow;
c = c%pow;
pow /= 10;
}
temp = a[1];
a[1] = a[5];
a[5] = a[6];
a[6] = a[2];
a[2] = temp;
return toSingleNum(a);
}
Node bfs(int M, int goal) {
Node u,v;
queue<Node> q;
u.a = 12348765;
u.path = "";
if( u.a == goal )
return u;
q.push(u);
while( !q.empty() ) {
u = q.front();
q.pop();
if( u.a == goal )
return u;
if( u.path.size() > M ) {
v.a = 0;
v.path = "";
return v;
}
v.a = A(u.a);
v.path = u.path + "A";
q.push(v);
v.a = B(u.a);
v.path = u.path + "B";
q.push(v);
v.a = C(u.a);
v.path = u.path + "C";
q.push(v);
}
}
int main() {
int i;
int a[8] = { 1, 2, 3, 4 , 8, 7, 6, 5 };
int b[8];
char path[10];
int M;
//cout << tosinglenum(a) << endl;
//cout << 1e4 << endl;
//print(a(tosinglenum(a)));
//print(b(tosinglenum(a)));
//print(c(tosinglenum(a)));
//system("pause");
cin >> M;
while( M != -1 ) {
for( i = 0; i < 4; i++ )
cin >> b[i];
for ( i = 4; i < 8; i++ )
cin >> b[i];
Node s = bfs(M, toSingleNum(b));
if( s.a == 0 ) {
cout << "-1" << endl;
}else{
cout << s.path.size() << " " << s.path << endl;
}
cin >> M;
}
return 0;
}
















