博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj1077
阅读量:7077 次
发布时间:2019-06-28

本文共 3148 字,大约阅读时间需要 10 分钟。

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

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

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

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

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

 

转载地址:http://obpml.baihongyu.com/

你可能感兴趣的文章
Linux下Tomcat复制一个新的文件夹后无法启动的问题
查看>>
Linux编程 16 文件权限(组管理 groupadd, groupmod,文件权限介绍)
查看>>
哈佛为什么群星闪耀?
查看>>
hdu5521 Meeting
查看>>
android学习笔记之handler(2)
查看>>
【LeetCode每天一题】Group Anagrams(变位词组)
查看>>
python学习笔记(五)文件操作和集合
查看>>
读书笔记之 programming wp7 之textblock
查看>>
使用@ResponseBody 出现错误Could not find acceptable representation
查看>>
Redis + Jedis + Spring整合遇到的异常(转)
查看>>
Nagios监控系统部署(源码)
查看>>
Python中的commands模块
查看>>
前端之CSS:CSS补充
查看>>
linux找不到主机名解决办法
查看>>
html,jquery,ajax,servlet,mysql实现前端数据写入数据库
查看>>
验证码
查看>>
ajax01
查看>>
React Native 环境搭建
查看>>
leetcode------Excel Sheet Column Title
查看>>
ceshi
查看>>