#include <QCoreApplication> #include <bits/stdc++.h> #include <iostream> #include <cstring> #include <stdio.h> using namespace std; #define N 4 #define N2 16 #define LIMIT 100 static const int dx[4] = {-1, 0, 1, 0}; static const int dy[4] = {0, -1, 0, 1}; static const char dir[4] = {'U','L','D','R'}; int MDT[N2][N2]; struct Puzzle { int f[N2]; //16个位置 int space; //空格的位置 int MD; }; Puzzle state; int limit; //深度限制 int path[LIMIT]; int getAllMD(Puzzle pz) { int sum = 0; for(int i = 0; i < N2; i++) { if(pz.f[i] == N2) continue; sum += MDT[i][pz.f[i]-1]; } return sum; } bool isSolve() { for(int i = 0; i < N2; i++) { if(state.f[i] != i+1) return false; } return true; } bool dfs(int depth, int prev) //深度和上一步方向 { if(state.MD == 0) return true; if(depth + state.MD > limit) //如果当前深度加上启发超过了限制,则进行剪纸 return false; int sx = state.space / N; int sy = state.space % N; Puzzle tmp; for(int r = 0; r < 4; r++) { int tx = sx + dx[r]; int ty = sy + dy[r]; if(tx < 0 || ty < 0 || tx >= N || ty >= N) continue; if(max(prev, r) - min(prev, r) == 2) //防止走回去,两个相反的方向相差2 continue; tmp = state; state.MD -= MDT[tx*N+ty][state.f[tx*N+ty] - 1]; state.MD += MDT[sx*N+sy][state.f[tx*N+ty] - 1]; swap(state.f[tx*N+ty], state.f[sx*N+sy]); state.space = tx*N+ty; if(dfs(depth+1, r)) //如果这一步探索成功 { path[depth] = r; return true; } state = tmp; //退回原来的状态 } return false; } string iterative_deepening(Puzzle in) { in.MD = getAllMD(in); //初始状态下的曼哈顿距离 for(limit = in.MD; limit <= LIMIT; limit++) { state = in; if(dfs(0, -100)) { string ans = ""; for(int i = 0; i < limit; i++) ans += dir[path[i]]; return ans; } } return "unsolvable"; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); freopen("G:\\data.txt", "r", stdin); for(int i = 0; i < N2; i++) { for(int j = 0; j < N2; j++) { MDT[i][j] = abs[i/N-j/N] + abs(i%N-j%N); } } Puzzle in; for(int i = 0; i < N2; i++) { cin >> in.f[i]; if(in.f[i] == 0) { in.f[i] = N2; in.space = i; } } string ans = iterative_deepening(in); cout << ans << " " << ans.size() << endl; return a.exec(); }