题目链接

题意

中文题意

思路

做这题的前置技能学习

  1. 康托展开

    这个东西我认为就是在排列组合问题上的Hash算法,可以压缩空间。

  2. A*搜索。

    这里我使用了像k短路一样的做法,从最终状态倒回去预处理一遍距离,但是跑了0.8s,可能是预处理花费的时间太多了。有些人用曼哈顿距离估价,跑了0.2s。

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
typedef long long LL;
struct Node {
int x, y, f, g, kt, mm[4][4];
bool operator < (const Node &rhs) const {
return f > rhs.f;
}
};
int init[4][4] = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 0 }
};
int mp[4][4], ans, h[500001], vis[500001], target;
int f[10], dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}; int kangtuo(int mp[4][4]) {
int sum = 0;
for(int i = 0; i < 9; i++) {
int now = 0;
for(int j = i + 1; j < 9; j++) {
if(mp[i/3][i%3] > mp[j/3][j%3]) now++;
}
sum += now * f[9-i-1];
} return sum + 1;
} void BFS(int x, int y) {
memset(h, INF, sizeof(h));
queue<Node> que;
Node now = (Node) {x, y, 0, 0};
for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
now.mm[i][j] = init[i][j];
h[target] = 0;
que.push(now);
while(!que.empty()) {
Node now = que.front(); que.pop();
int x = now.x, y = now.y, f = now.f;
for(int i = 0; i < 4; i++) {
now.x = x + dx[i], now.y = y + dy[i];
if(now.x < 0 || now.x > 2 || now.y < 0 || now.y > 2) continue;
swap(now.mm[x][y], now.mm[now.x][now.y]);
int nf = f + 1, nkt = kangtuo(now.mm);
now.f = nf;
if(h[nkt] == INF) {
h[nkt] = nf;
que.push(now);
}
swap(now.mm[x][y], now.mm[now.x][now.y]);
}
}
} void YCL() {
BFS(2, 2);
} int Astar(int x, int y) {
priority_queue<Node> que;
memset(vis, 0, sizeof(vis));
vis[kangtuo(mp)] = 1;
Node now = (Node) { x, y, 0, 0, kangtuo(mp)};
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
now.mm[i][j] = mp[i][j];
que.push(now);
while(!que.empty()) {
now = que.top(); que.pop();
int x = now.x, y = now.y, f = now.f, g = now.g, kt = now.kt;
if(kt == target) return f;
for(int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || nx > 2 || ny < 0 || ny > 2) continue;
swap(now.mm[x][y], now.mm[nx][ny]);
int nkt = kangtuo(now.mm);
now.x = nx, now.y = ny, now.g = g + 1, now.f = now.g + h[nkt], now.kt = nkt;
if(!vis[nkt]) {
vis[nkt] = 1;
que.push(now);
}
swap(now.mm[x][y], now.mm[nx][ny]);
}
} return -1;
} int main() {
f[0] = 1;
for(int i = 1; i < 9; i++) f[i] = f[i-1] * (i);
target = kangtuo(init);
YCL();
int t; scanf("%d", &t);
while(t--) {
int ix, iy;
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++) {
scanf("%d", &mp[i][j]);
if(mp[i][j] == 0) ix = i, iy = j;
}
ans = Astar(ix, iy);
if(~ans) printf("%d\n", ans);
else puts("No Solution!");
}
return 0;
}

最新文章

  1. Spring异步功能
  2. Reveal分析IOS界面,plist文件读取
  3. 【bzoj3156】 防御准备
  4. UVA 11732 strcmp() Anyone? (压缩版字典树)
  5. php面试题之二——数据结构和算法(高级部分)
  6. 编写一个Java程序,计算一下1,2,…,9这9个数字可以组成多少个互不相同的、无重复数字的三位偶数。
  7. simplefactory简单工厂模式
  8. JPG各种输入框样式
  9. mysqldump 的一些使用参数
  10. python作用域 scope
  11. [C#]6.0新特性浅谈
  12. k-means算法的Python实现
  13. AI时代:推荐引擎正在塑造人类
  14. HBase数据持久化之HRegion.flushcache即CF持久化
  15. java代码理解
  16. Robotics Tools
  17. 20155306 2016-2017-2 《Java程序设计》第九周学习总结
  18. [蓝桥杯]ALGO-122.算法训练_未名湖边的烦恼
  19. .net DLL 注册 regasm delphi调用
  20. 有限状态机(FSM)的Java 学习FSM

热门文章

  1. DOS符号转义(转 http://www.robvanderwoude.com/escapechars.php)
  2. aravel 之父 Taylor Otwell :我是如何工作的
  3. CheckBox IsHitTestVisible
  4. JS enter代替tab,只有部分键可以代替
  5. 【C#】wpf自定义calendar日期选择控件的样式
  6. Qt侠:像写诗一样写代码,玩游戏一样的开心心情,还能领工资!
  7. 零元学Expression Blend 4 - Chapter 36 来玩捉迷藏吧!!!看看ScrollBar的Disabled与Hidden之差异
  8. winform picturebox设置布局样式
  9. Delphi中动态调用TXMLDocument的经历
  10. 2016最受欢迎国产开源软件评选,2016 年度开源中国新增开源软件排行榜 TOP 100