此题就是状态搜索题;使用bfs来获得最远的那个状态,然后打印出来,中间记录一下父节点就可以了。
此题需要注意到的技巧:
1.使用数组代替栈
2.hash函数的使用,将每个状态用整数表示。
3.memcpy整块内存的复制,memcmp整块内存的比较。
//
// main.cpp
// uva10085 The Most Distant State
//
// Created by XD on 15/8/4.
// Copyright (c) 2015年 XD. All rights reserved.
//
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include<vector>
#include <string.h>
#include <string>
#include <algorithm>
#include <set>
#include <map>
#include <cstdio>
using namespace std ;
typedef int State[10];
const int maxstate = 10000000 ;
int fa[maxstate] ;
State st[maxstate] , goal ;
int dist[maxstate] ;
const int dx[] = {-1,1,0,0} ;
const int dy[] = {0 ,0 ,-1 ,1} ;
const int hashsize = 1000003 ;
int head[hashsize] , mnext[maxstate] ;
int ans ;
void init_lookup_table()
{
memset(head, 0, sizeof(head)) ;
memset(mnext, 0, sizeof(mnext)) ;
memset(fa, 0, sizeof(fa)) ;
}
int Hash(State& s)
{
int v = 0 ;
for (int i = 0; i <9 ; i++) {
v = v * 10 + s[i] ;
}
return v % hashsize ;
}
int try_to_insert(int s)
{
int h = Hash(st[s]) ;
int u = head[h] ;
while (u) {
if (memcmp(st[u],st[s], sizeof(st[s]) - sizeof(int)) == 0 ) {
return 0 ;
}
u = mnext[u] ;
}
mnext[s] = head[h] ;
head[h] = s ;
return 1 ;
}
int bfs()
{
init_lookup_table() ;
int front = 1 , rear = 2 ;
while (front < rear) {
State& s = st[front] ;
if (front + 1 ==rear) {
ans =front ;
}
int z ;
for (int i = 0; i < 9 ; i++) {
if (s[i] == 0 ) {
z = i ;
break ;
}
}
int x = z / 3 ; int y = z%3 ;
for (int i = 0 ; i< 4; i++) {
int newx = x + dx[i] ;
int newy = y + dy[i] ;
int newz = newx * 3 + newy ;
if (newx >= 0 && newy>= 0&& newx <3&& newy<3) {
State& t = st[rear] ;
memcpy(&t, &s, sizeof(s)) ;
t[newz] = s[z] ;
t[z] = s[newz] ;
t[9] = i ;
dist[rear] = dist[front] + 1;
if (try_to_insert(rear)) {
fa[rear] = front ;
rear++ ;
}
}
}
front++ ;
}
return ans ;
}
int main(int argc, const char * argv[]) {
int j = 0;
int casenum ;
scanf("%d" ,&casenum) ;
while (casenum--) {
printf("Puzzle #%d\n" , ++j) ;
for (int i = 0 ; i < 9 ; i++) {
scanf("%d" , &st[1][i]) ;
}
bfs() ;
for (int i = 0; i < 9; i++) {
printf("%d " ,st[ans][i]) ;
if (i % 3 == 2) {
printf("\n") ;
}
}
vector<char> anspath ;
anspath.clear() ;
while (ans != 1 ) {
char direct ;
switch (st[ans][9]) {
case 0:
direct = 'U' ;
break;
case 1:
direct = 'D' ;
break ;
case 2:
direct = 'L' ;
break ;
case 3 :
direct = 'R' ;
break ;
default:
break;
}
anspath.push_back(direct) ;
ans = fa[ans] ;
}
int len =(int ) anspath.size() ;
for (int i = len-1 ; i >= 0; i--) {
printf("%c" , anspath[i]) ;
}
cout << endl <<endl ;
}
return 0;
}