问题 C: 【宽搜入门】8数码难题
时间限制: 20 Sec 内存限制: 128 MB
提交: 85 解决: 26
[提交][状态][讨论版][命题人:外部导入]
题目描述
初始状态的步数就算1,哈哈
输入:第一个3*3的矩阵是原始状态,第二个3*3的矩阵是目标状态。
输出:移动所用最少的步数
Input
2 8 3
1 6 4
7 0 5
1 2 3
8 0 4
7 6 5
Output
6
#include<iostream>
#include<cstdio>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
int start, termination, pos;
struct node {
int num, step, pos;//状态、步数、0的下标
node(int n, int s, int p) {
num = n, step = s, pos = p;
}
};
int oper(char str[], int p, int flag, bool operate) {
if (flag == 0 && operate || flag == 1 && !operate) {//up
if (p < 3)return -1;
swap(str[p], str[p - 3]);
return p - 3;
}
else if (flag == 1 && operate || flag == 0 && !operate) {//down
if (p >= 6) return -1;
swap(str[p], str[p + 3]);
return p + 3;
}
else if (flag == 2 && operate || flag == 3 && !operate){//left
if (p % 3 == 0)return -1;
swap(str[p], str[p - 1]);
return p - 1;
}
else {//right
if (p % 3 == 2)return -1;
swap(str[p], str[p + 1]);
return p + 1;
}
}
queue<node> q;
map<int, bool> mp;
void BFS() {
char temp[10];
int temp1;
node s(start, 1, pos);
q.push(s);
mp[start] = true;
while (!q.empty()) {
s = q.front();
q.pop();
if (s.num == termination) {
cout << s.step << endl;
return;
}
sprintf(temp, "%d", s.num);
if (s.num < 100000000) {//注意第一个数字为0时转换
for (int i = 8; i > 0; i--) {
temp[i] = temp[i - 1];
}
temp[0] = '0';
}
for (int i = 0; i < 4; i++) {
int d = oper(temp, s.pos, i, true);
if (d == -1)continue;
sscanf(temp, "%d", &temp1);
if (mp.count(temp1) == 0) {
node r(temp1, s.step + 1, d);
q.push(r);
mp[temp1] = true;
}
oper(temp, d, i, false);
}
}
}
int main() {
int n;
while (cin >> n) {
if (n == 0) pos = 0;
start = n, termination = 0;
for (int i = 1; i < 9; i++) {
cin >> n;
start = start * 10 + n;
if (n == 0) pos = i;
}
for (int i = 0; i < 9; i++) {
cin >> n;
termination = termination * 10 + n;
}
BFS();
}
return 0;
}