题意:给出一个八数码问题,求解法,不可解则输出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 ;
}

poj1077的更多相关文章

  1. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

  2. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  3. POJ1077 Eight —— 经典的搜索问题

    题目链接:http://poj.org/problem?id=1077 Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submission ...

  4. poj1077 Eight【爆搜+Hash(脸题-_-b)】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4298840.html   ---by 墨染之樱花 题目链接:http://poj.org/pr ...

  5. POJ1077&&HDU1043(八数码,IDA*+曼哈顿距离)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30127   Accepted: 13108   Special ...

  6. poj1077(康托展开+bfs+记忆路径)

    题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如: 1 2 3 现在,需要你把它变成:1 2 3 要的最少步数的移动方案.可以右移r,左移l,上移u,下移dx 4 6 4 5 67 ...

  7. POJ1077 Eight A*

    这个题扔到A*可也还行... 定义估价函数h():为每个数或空格的位置 到 最终状态中所在位置 的 曼哈顿距离 的 总和. 把状态压成一个九进制数,便于存储和判重. 然后记录方案可以记录一下此次的操作 ...

  8. POJ1077 八数码 BFS

    BFS 几天的超时... A*算法不会,哪天再看去了. /* 倒搜超时, 改成顺序搜超时 然后把记录路径改成只记录当前点的操作,把上次的位置记录下AC..不完整的人生啊 */ #include < ...

  9. POJ1077 Eight —— IDA*算法

    主页面:http://www.cnblogs.com/DOLFAMINGO/p/7538588.html 代码一:像BFS那样,把棋盘数组放在结构体中. #include <iostream&g ...

随机推荐

  1. yii2 查询数据库语法

    $query0 = ImGroupUser::find()->where(['gid'=>'56680dfc60b215d62104a4d8'])->select('user_cli ...

  2. POJ 2155 Matrix (矩形)

    date:公元2017年7月19日适逢周三: location:清北集训 杭州 point:二维树状数组/二维差分 Matrix Time Limit: 3000MS   Memory Limit:  ...

  3. BZOJ5389 比例查询 【离线】

    题目链接 BZOJ5389 题解 太\(sb\)了,这种题都想不出来 发现复杂度允许\(n\sqrt{n}\),我们可以对于每个位置\(\sqrt{n}\)枚举约数,然后维护比例的最晚出现的位置,维护 ...

  4. 【bzoj1483】 HNOI2009—梦幻布丁

    http://www.lydsy.com/JudgeOnline/problem.php?id=1483 (题目链接) 题意 $n$个布丁摆成一行,进行$m$次操作.每次将某个颜色的布丁全部变成另一种 ...

  5. [转]Multivariate Time Series Forecasting with LSTMs in Keras

    1. Air Pollution Forecasting In this tutorial, we are going to use the Air Quality dataset. This is ...

  6. 南昌邀请赛网络赛 D.Match Stick Game(dp)

    南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...

  7. vim文件头部注释配置

    http://note.youdao.com/noteshare?id=26dff538fabf3e8a0c4e85815256d5bb

  8. Java基础-IO流对象之字节流(Stream)

    Java基础-IO流对象之字节流(Stream) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在前面我分享的笔记中,我们一直都是在操作文件或者文件夹,并没有给文件中写任何数据.现 ...

  9. C语言中的指针和内存泄漏几种情况

    引言 原文地址:http://www.cnblogs.com/archimedes/p/c-point-memory-leak.html,转载请注明源地址. 对于任何使用C语言的人,如果问他们C语言的 ...

  10. angularJS__v1.5.6点击同一个菜单刷新

    针对angularjs的1.0版本,点击菜单不刷新问题,只需在配置路由时,路由路径添加“/”,如,点击 标签时,就会刷新,