题意:给出一个八数码问题,求解法,不可解则输出unsolvable。

分析:可以用ida*算法,估价函数可以使用每个数码到其最终位置的最短距离之和。对于不可解的判断,我这里用迭代深度大于100时判定为不可解。

还有一种更高级的无解判断方法。就是将八数码矩阵中的空格忽略,然后将8个数字排成一排,第二行接在第一行后面,第三行接在第二行后面,通过观察我们发现移动空格不会影响这个8个数字组成的数列中逆序数队的奇偶性,因此如果逆序数对的奇偶性与目标状态不同则一定无解。至于为什么奇偶性相同就一定有解,我就不知道为什么了,不过这个命题确实是正确的。

可以将这种方法做适当修改并推广至15数码问题。

#include <iostream>
#include <stack>
#include <cmath>
using namespace std; const int maxn = ; char ans[];
int tot, dir[][] = {{-,},{,},{,},{,-}}; struct Node
{
char map[maxn];
int g, move, xpos;
}starts; void init()
{
for (int i = ; i < ; i++)
{
starts.map[i] = ' ';
while (starts.map[i] == ' ')
scanf("%c",&starts.map[i]);
if (starts.map[i] == 'x')
{
starts.map[i] = ;
starts.xpos = i;
} else
starts.map[i] -= '';
}
} int h(Node &a)
{
int x1, x2, y1, y2, i, r = ; for (i = ; i < ; i++)
{
x1 = i / ;
y1 = i % ;
x2 = (a.map[i] - ) / ;
y2 = (a.map[i] - ) % ;
r += abs(x1 - x2) + abs(y1 - y2);
}
return r;
} Node getchild(int a, Node &currents)
{
int x, y, pos, i;
Node r; x = currents.xpos / + dir[a][];
y = currents.xpos % + dir[a][];
r.xpos = -;
if (x < || y < || x > || y > )
return r;
pos = x * + y;
r.xpos = pos;
r.g = currents.g + ;
r.move = a;
for (i = ; i < ; i++)
r.map[i] = currents.map[i];
r.map[pos] = ;
r.map[currents.xpos] = currents.map[pos];
return r;
} bool ida()
{
int pathlimit, i, temp, next;
bool success = ;
Node currents, child; next = h(starts)/;
stack<Node> stk;
do
{
pathlimit = next;
if (pathlimit > )
return false;
tot = ;
starts.g = ;
starts.move = -;
next = ;
stk.push(starts);
do
{
currents = stk.top();
ans[currents.g] = currents.move;
stk.pop();
temp = h(currents);
if (temp == )
{
tot = currents.g;
success = true;
}
else if (pathlimit >= currents.g + temp / )
{
for (i = ; i < ; i++)
{
child = getchild(i, currents);
if (child.xpos != - && abs(child.move - currents.move) != )
stk.push(child);
}
}else if (next > currents.g + temp / )
next = currents.g + temp / ;
}while (!success && !stk.empty());
}while (!success);
return true;
} void print()
{
int i; for (i = ; i <= tot; i++)
switch(ans[i])
{
case : printf("u"); break;
case : printf("r"); break;
case : printf("d"); break;
case : printf("l"); break;
}
printf("\n");
} int main()
{
//freopen("t.txt", "r", stdin);
init();
if (ida())
print();
else
printf("unsolvable\n");
return ;
}

最新文章

  1. 关于P,V操作理解的突破,关于并发设计与并行
  2. vi使用
  3. 常用 SQL 语句
  4. iOS 中 #import同@class之间的区别
  5. [原]Django慢请求分析工具--dogslow
  6. HDU 2853 Assignment(KM最大匹配好题)
  7. CSS制作水平垂直居中对齐
  8. 原生js实现轮播图
  9. Oracle_rowid_rownum分页
  10. hibernate(二)主键生成策略
  11. Linux内核模块编程——Hello World模块
  12. Spark之Yarn提交模式
  13. 消除 ASP.NET Core 告警 &quot;No XML encryptor configured. Key may be persisted to storage in unencrypted form&quot;
  14. vue 点击图片放大
  15. How Region Split works in Hbase
  16. 图像小波变换去噪——MATLAB实现
  17. python 多进程、多线程
  18. 13.1SolrCloud集群使用手册之Collections API
  19. Java常考面试题(一)
  20. Linux交叉编译工具链和模块编译

热门文章

  1. hdu6057 Kanade&#39;s convolution 【FWT】
  2. 20135319zl elf文件报告
  3. Windows + Ubuntu下JDK与adb/android环境变量配置完整教程
  4. 导入eclipse工程到Android Studio中
  5. CDOJ--1141
  6. 【Asp.net入门5-02】创建数据模型和存储库
  7. Kubernetes PV/PVC使用实践
  8. P3275 [SCOI2011]糖果 &amp;&amp; 差分约束(二)
  9. day10 浅谈面向对象编程
  10. Qt_扫雷游戏实现