poj 1077(BFS预处理+康托展开)
| Time Limit: 1000MS | Memory Limit: 65536K | |||
| Total Submissions: 29935 | Accepted: 13029 | Special Judge | ||
Description
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 x
where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle:
1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4
5 6 7 8 5 6 7 8 5 6 7 8 5 6 7 8
9 x 10 12 9 10 x 12 9 10 11 12 9 10 11 12
13 14 11 15 13 14 11 15 13 14 x 15 13 14 15 x
r-> d-> r->
The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively.
Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course).
In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three
arrangement.
Input
1 2 3
x 4 6
7 5 8
is described by this list:
1 2 3 x 4 6 7 5 8
Output
Sample Input
2 3 4 1 5 x 7 6 8
Sample Output
ullddrurdllurdruldr 题意:经典八数码
题解:预处理终点到所有状态的路径。康拓展开保存状态
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
const int N = ;
int fab[] = {,,,,,,,,};
bool vis[N];
struct Node{
int a[];
int Hash;
int _x; ///x所在位置
};
struct Way{
char c;
int pre;
}way[N];
int contor(Node s){
int sum = ;
for(int i=;i>=;i--){
int cnt = ;
for(int j=i-;j>=;j--){
if(s.a[i]<s.a[j]) cnt++;
}
sum+=fab[i-]*cnt;
}
return sum;
}
int dir[][] = {{-,},{,},{,-},{,}}; ///上下左右
bool change(Node &s,int _x,int k){
int x = (_x-)/+;
int y = _x%==?:_x%;
int nextx = x+dir[k][];
int nexty = y+dir[k][];
if(nextx<||nexty>||nexty<||nexty>) return false;
swap(s.a[_x],s.a[(nextx-)*+nexty]);
s._x = (nextx-)*+nexty;
return true;
}
void bfs(){
for(int i=;i<N;i++){
way[i].pre = -;
}
memset(vis,false,sizeof(vis));
Node s;
for(int i=;i<=;i++){
s.a[i] = i;
}
s.Hash = ,s._x = ;
vis[] = ;
queue<Node> q;
q.push(s);
while(!q.empty()){
Node now = q.front();
q.pop();
Node next;
next = now;
if(change(next,next._x,)){
int k = contor(next);
if(!vis[k]){
vis[k] = true;
next.Hash = k;
way[k].pre = now.Hash;
way[k].c = 'd';
q.push(next);
}
}
next = now;
if(change(next,next._x,)){
int k = contor(next);
if(!vis[k]){
vis[k] = true;
next.Hash = k;
way[k].pre = now.Hash;
way[k].c = 'u';
q.push(next);
}
}
next = now;
if(change(next,next._x,)){
int k = contor(next);
if(!vis[k]){
vis[k] = true;
next.Hash = k;
way[k].pre = now.Hash;
way[k].c = 'r';
q.push(next);
}
}
next = now;
if(change(next,next._x,)){
int k = contor(next);
if(!vis[k]){
vis[k] = true;
next.Hash = k;
way[k].pre = now.Hash;
way[k].c = 'l';
q.push(next);
}
}
}
}
char str[];
char ans[];
int t = ;
void dfs(int k){
if(way[k].pre==-) return;
dfs(way[k].pre);
ans[t++]=way[k].c;
}
int main()
{
bfs();
while(scanf("%s",str)!=EOF){
Node s;
s.a[] = (str[]=='x')?:str[]-'';
for(int i=;i<=;i++){
scanf("%s",str);
s.a[i] = (str[]=='x')?:str[]-'';
}
int k = contor(s);
ans;
t = ;
dfs(k);
if(t==){
printf("unsolvable\n");
continue;
}
for(int i=t-;i>=;i--){
printf("%c",ans[i]);
}
printf("\n");
}
return ;
}
poj 1077(BFS预处理+康托展开)的更多相关文章
- HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30176 Accepted: 13119 Special ...
- HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30176 Accepted: 13119 Special ...
- HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】
本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...
- HDU_1430——魔板,预处理,康托展开,置换,string类的+操作
Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可 ...
- HDU - 1430 魔板 (bfs预处理 + 康托)
对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...
- POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- POJ 1077 && HDU 1043 Eight A*算法,bfs,康托展开,hash 难度:3
http://poj.org/problem?id=1077 http://acm.hdu.edu.cn/showproblem.php?pid=1043 X=a[n]*(n-1)!+a[n-1]*( ...
- POJ 1077 Eight (BFS+康托展开)详解
本题知识点和基本代码来自<算法竞赛 入门到进阶>(作者:罗勇军 郭卫斌) 如有问题欢迎巨巨们提出 题意:八数码问题是在一个3*3的棋盘上放置编号为1~8的方块,其中有一块为控制,与空格相邻 ...
随机推荐
- 洛谷P1268 树的重量 【构造 + 枚举】
题目描述 树可以用来表示物种之间的进化关系.一棵"进化树"是一个带边权的树,其叶节点表示一个物种,两个叶节点之间的距离表示两个物种的差异.现在,一个重要的问题是,根据物种之间的距离 ...
- Mysql千万级大表优化策略
1.优化sql以及索引 1.1优化sql 1.有索引但未被用到的情况(不建议) (1)避免like的参数以通配符开头时 尽量避免Like的参数以通配符开头,否则数据库引擎会放弃使用索引而进行全表扫描. ...
- Qt实现截屏并保存(转载)
原博地址:http://blog.csdn.net/qinchunwuhui/article/details/52869451?_t_t_t=0.28889142944202306 目前对应用实现截屏 ...
- 徒手创建一个 jsp 项目
在开始之前,先回顾一下 jsp 和 servlet,jsp 和 servlet 本质是一样的,因为 jsp 最终必须编译成 servlet 才能运行. 因为 jsp 的那些标签 jvm 是无法直接运行 ...
- java 根据包名、目录名获取所有定义的类
/** * Scans all classes accessible from the context class loader which belong to the given package a ...
- ios 逆向
Theos https://www.jianshu.com/p/307243ea40e4 Dumpsdecrypted https://www.cnblogs.com/wangyaoguo/p/908 ...
- [ldap]slapcat/ldapsearch与ldap备份
http://serverfault.com/questions/577356/ldap-backup-with-slapcat-vs-ldapsearch Used: openldap-server ...
- WPF系列之三:实现类型安全的INotifyPropertyChanged接口,可以不用“Magic string” 么?
通常实现INotifyPropertyChanged接口很简单,为你的类只实现一个PropertyChanged 的Event就可以了. 例如实现一个简单的ViewModel1类: public cl ...
- 如何识别字符串是否是UTF-8编码的
我们先要弄明白原始字符串里的字符用的是何种编码方式,运行如下 string tmp = "你好world"; for(int i=0;i<tmp.size();++i) { ...
- [LeetCode] 数学计算模拟类问题:加法,除法和幂,注意越界问题。题 剑指Offer,Pow(x, n) ,Divide Two Integers
引言 数学计算的模拟类题目,往往是要求实现某种计算(比如两数相除),实现的过程中会有所限定,比如不允许乘法等等. 这类题目首先要注意计算过程中本身的特殊情况.比如求相除,则必须首先反映过来除数不能为0 ...