Hdu 1043 Eight (八数码问题)
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1043
题目描述:
3*3的格子,填有1到8,8个数字,还有一个x,x可以上下左右移动,问最终能否移动到12345678x的状态?
hint:每一个3*3的格子从上到右,从左到右,一行一行读。
解题思路:
比较简单的八数码问题,大一暑假老师讲过,一直手懒脑懒并没有亲自尝试过。因为是多实例,先从12345678x的状态bfs出来所有可以到达的状态,并且记录下来路径。八数码最重要的就是保存状态,如果这个题目用十进制保存状态的话,至少要到达10^9的数量级。可以利用康拓展开hash搜索到的状态,空间可以缩小到9!(ง •̀_•́)ง
#include <stdio.h>
#include <string.h>
#include <string>
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std; #define maxn 370000
struct node
{
string path;//路径
int s[]; //state
int loc; //9的位置
int ct; //康拓hash
};
int fac[] = {, , , , , , , *, **, ***};
//0!,1!,2!....9!
int dir[][] = {,, ,-, -,, ,}; // r, l, u, d
int vis[maxn];
char di[] = "lrdu"; //l, r, d, u
string path[maxn];
void init ()
{
memset (vis, , sizeof(vis));
} int cantor (int a[]) //康拓hash
{
int sum = ;
for (int i=; i<; i++)
{
int m = ;
for (int j=i+; j<; j++)
if (a[j] < a[i])
m ++;
sum += m * (fac[-i-]);
}
return sum + ;
} void bfs ()
{
node cur, next;
queue <node> Q; for(int i=; i<; i++)
cur.s[i] = i + ;
cur.s[] = ;
cur.ct = cantor (cur.s);
cur.loc = ; Q.push (cur);
vis[cur.ct] = ;
path[cur.ct] = ""; while (!Q.empty())
{
cur = Q.front();
Q.pop (); for (int i=; i<; i++)
{
int x = cur.loc / + dir[i][];
int y = cur.loc % + dir[i][];
if (x< || x> || y< || y>)
continue;
next = cur;
next.loc = x * + y;
next.s[cur.loc] = next.s[next.loc];
next.s[next.loc] = ;
next.ct = cantor (next.s);
if (!vis[next.ct])
{
vis[next.ct] = ;
path[next.ct] = di[i] + path[cur.ct];
Q.push (next);
}
}
} } int main ()
{
init ();
bfs ();
char s[];
int a[]; while (scanf ("%s", s) != EOF)
{
if (s[] == 'x')
a[] = ;
else
a[] = s[] - ''; for (int i=; i<; i++)
{
scanf ("%s", s);
if (s[] == 'x')
a[i] = ;
else
a[i] = s[] - '';
}
int m = cantor (a);
if (vis[m])
cout<<path[m]<<endl;
else
puts ("unsolvable");
}
return ;
}
Hdu 1043 Eight (八数码问题)的更多相关文章
- HDU 1043 Eight 八数码问题 A*算法(经典问题)
HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...
- hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】
<题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为 ...
- HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法
先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...
- 【双向广搜+逆序数优化】【HDU1043】【八数码】
HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...
- hdu 1043 Eight 经典八数码问题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 The 15-puzzle has been around for over 100 years ...
- HDU 1043 Eight(八数码)
HDU 1043 Eight(八数码) 00 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Descr ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
- HDU 1043 Eight (BFS·八数码·康托展开)
题意 输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数 即这个排列在全部排列中的字典序 然后就是基础的BFS了 #include <bits/stdc++.h ...
- HDU 1043 八数码(A*搜索)
在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...
随机推荐
- linux进程间通信消息队列:msgsnd: Invalid argument
今天写了个消息队列的小测试程序结果send端程序总是出现:msgsnd: Invalid argument,搞了半个小时也没搞明白,后来查资料发现我将(st_msg_buf.msg_type = 0; ...
- SpringMVC -- 第一个简单的程序
学习springMVC,我们来记录下第一个HelloWord的程序 首先.我们组织须要的jar包 commons-logging-1.1.3.jar spring-aop-4.1.7.RELEASE. ...
- java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述
猛击这里 java的nio包的SelectionKey,Selector,SelectableChannel三者的缠绵关系概述
- Facebook内部高效工作指南
文章来源: TopDigital http://news.ittime.com.cn/usershow/main?userid=2826 [IT时代网.IT时代周刊编者按]每一个人工作中都会遇到力不从 ...
- python的对象的属性(即对象的成员)是动态的
1 python的对象的成员叫attribute 2 python的类的成员是可以动态创建的 因此,在用的时候也提供了三个内建的接口来对类的成员进行操作 2.1 getattr() 2.2 hasat ...
- Java客户端:调用EyeKey HTTP接口进行人脸对比
package com.example.buyishi; import java.io.BufferedReader; import java.io.IOException; import java. ...
- KbmMW资源汇总(特别是xalion的文章)
KbmMW框架是收费的,不在此提供下载,如需购买,请自行联系作者Kim Madsen. 网址资源: 官网主页:http://www.components4programmers.com/product ...
- flywaydb and sql server
https://flywaydb.org/documentation/database/sqlserver How Flyway works https://flywaydb.org/getstart ...
- YTU 2421: C语言习题 矩形法求定积分
2421: C语言习题 矩形法求定积分 时间限制: 1 Sec 内存限制: 128 MB 提交: 354 解决: 234 题目描述 写一个用矩形法求定积分的通用函数,分别求 (说明: sin,co ...
- YTU 2427: C语言习题 整数排序
2427: C语言习题 整数排序 时间限制: 1 Sec 内存限制: 128 MB 提交: 391 解决: 282 题目描述 用指向指针的指针的方法对n个整数排序并输出.要求将排序单独写成一个函数 ...