在详细的讲解了一下康拓展开和A*搜索后,我们终于迎来了对八数码问题的致命一击,那这里我就秉承之前的解题报告流程,一不要怪我官方啊;;
1.题意:
此题是一个经典的老提,就是给出一个方阵,你要输出基本的路径,使得方阵为1,2,3,4,5,6,7,8,x;
2.思路:
太简单的思路了,就是一个简单的搜索,如果不是会超时,要寻找一个更合适的方案,是不会有人做的;;
3.如何针对超时:
这个问题的解法就是之前讨论的,也就是用A*算法,可以避免广搜的盲目性;
一下附上AC代码,375ms,然后就是哈希判重我感觉没必要,只要在pop时看看是不是close列表中的就可以了,,不需要去判重,可能这就是我使用了A*还是300多ms的愿因吧;;;
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string>
#include<math.h>
#define close -1
using namespace std;
struct node{
int deep;
int priority;
int map[9];
string path;
int space;
friend bool operator < (node a,node b){
return a.priority > b.priority ;
}
};
node start,end;
bool visit[368881];
int op[4] = {-3,3,-1,1};
char dir[4] = {'u','d','l','r'};
int jie[10] = {1,1,2,6,24,120,720,5040, 40320, 362880};
int judge(node start){
for(int i=0;i<9;i++){
if(start.map[i] != i + 1){
return false;
}
}
return true;
}
int get_value(int x){
if(x == 0) return 0;
if(x == 1) return 1;
if(x == 2) return 2;
if(x == 3) return 1;
return get_value(x-3) + 1;
}
int get_priority(node x){
int value=0,num;
for(int i=0;i<9;i++){
num = fabs(x.map[i] - i -1);
value += get_value(num);
}
return value+x.deep;
}
int canto(node start){
int num,value=0;
for(int i=0;i<9;i++){
num = 0;
for(int j=i+1;j<9;j++){
if(start.map[j]<start.map[i]){
num++;
}
}
value += jie[8-i]*num;
}
return value;
}
int BFS(){
node now,bow;
priority_queue<node>q;
q.push(start);
visit[canto(start)] = 1;
while(!q.empty()){
now = q.top();
int t = canto(now);
if(visit[t] == close){
continue;
}
q.pop();
visit[t] = close;
if(judge(now)){
end = now;
return true;
}
for(int i=0;i<4;i++){
bow = now;
if(i==2&&(bow.space == 3||bow.space == 6)){
continue;
}
if(i==3&&(bow.space == 2||bow.space == 5)){
continue;
}
bow.space = now.space + op[i] ;
if(bow.space>=0&&bow.space<=8){
swap(bow.map[bow.space],bow.map[now.space]);
int c = canto(bow);
if(visit[c] == close) continue;
if(visit[c] == 0 ){
bow.deep ++;
bow.path += dir[i];
bow.priority = get_priority(bow);
visit[c] = 1;
q.push(bow);
}
}
}
}
return false;
}
int main(){
char c;
for(int z = 0;z < 9;z++){
c = getchar();
getchar();
if(c == 'x'){
start.space = z;
start.map[z] = 9;
}
else{
start.map[z] = c - '0';
}
}
// cout<<"ok"<<endl;
if(BFS() == 1){
cout<<end.path<<endl;
}
else
cout<<"unsolveable"<<endl;
}