题目摘要
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变
#include <iostream>
#include <cstring>
#include <queue>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#include <set>
using namespace std;
string strStart,strEnd = "123804765";
set <string> strSet;
struct Node{
int level;
string value;
Node(){}
Node(int l,string v):level(l),value(v){}
};
queue <Node> q;
string move(string s,int op){
int zeroIndex = 0;
for (int i = 0; i < s.length(); ++i) {
if(s[i] == '0'){
zeroIndex = i;
break;
}
}
string tmp = s;
switch (op){
case 0:
if(zeroIndex > 2){
swap(tmp[zeroIndex],tmp[zeroIndex-3]);
}
break;
case 1:
if(zeroIndex < 6){
swap(tmp[zeroIndex],tmp[zeroIndex+3]);
}
break;
case 2:
if(zeroIndex % 3 != 0){
swap(tmp[zeroIndex],tmp[zeroIndex-1]);
}
break;
case 3:
if(zeroIndex % 3 != 2){
swap(tmp[zeroIndex],tmp[zeroIndex+1]);
}
break;
}
return tmp;
}
int main(){
cin >> strStart;
if(strStart == strEnd)
cout << 0 << endl;
q.push(Node(0,strStart));
strSet.insert(strStart);
Node tmp;
string strTmp;
while (!q.empty()){
tmp = q.front();
q.pop();
for (int i = 0; i < 4; ++i) {
strTmp = move(tmp.value,i);
if(strTmp == tmp.value)
continue;
if(strTmp == strEnd){
cout << tmp.level+1 << endl;
return 0;
}
if(strSet.count(strTmp) == 0){
q.push(Node(tmp.level + 1,strTmp));
strSet.insert(strTmp);
}
}
}
cout << -1 << endl;
return 0;
}