hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)
http://acm.hdu.edu.cn/showproblem.php?pid=1043
http://poj.org/problem?id=1077
Eight
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9173 Accepted Submission(s): 2473 Special Judge
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.
1 2 3
is described by this list:
1 2 3 x 4 6 7 5 8
{1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个。123 132 213 231 312 321 。
代表的数字 1 2 3 4 5 6 也就是把10进制数与一个排列对应起来。
他们间的对应关系可由康托展开来找到。
如我想知道321是{1,2,3}中第几个大的数可以这样考虑 :
第一位是3,当第一位的数小于3时,那排列数小于321 如 123、 213 ,小于3的数有1、2 。所以有2*2!个。再看小于第二位2的:小于2的数只有一个就是1 ,
所以有1*1!=1 所以小于321的{1,2,3}排列数有2*2!+1*1!=5个。所以321是第6个大的数。 2*2!+1*1!+0*0!就是康托展开。
再举个例子:1324是{1,2,3,4}排列数中第几个大的数:第一位是1小于1的数没有,是0个 0*3! 第二位是3小于3的数有1和2,但1已经在第一位了,
所以只有一个数2 1*2! 。第三位是2小于2的数是1,但1在第一位,所以有0个数 0*1! ,所以比1324小的排列有0*3!+1*2!+0*1!=2个,1324是第三个大数。
#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h> using namespace std;
#define N 363000 struct Nod
{
int b[];
int x,y,pos;
}nd1,nd2; int fac[] = {,,,,,,,,,}; //康拓展开用到的数组
//康托展开:
int cantor(int* a, int k)
{
int i, j, tmp, num = ;
for (i = ; i < k; i++) {
tmp = ;
for (j = i + ; j < k; j++)
if (a[j] < a[i])
tmp++;
num += fac[k - i - ] * tmp;
}
return num;
} int mark[N],pre[N];
char dir[N];
int cx[]={,,,-};
int cy[]={-,,,}; void exchange(int *a,int x,int y)
{
int temp=a[x];
a[x]=a[y];
a[y]=temp;
} void bfs(int *b,int x,int y)
{
queue<Nod> q;
memset(mark,,sizeof(mark));
memset(pre,-,sizeof(pre));
nd1.x=x;
nd1.y=y;
memcpy(nd1.b,b,sizeof(int)*);
int i,temp;
temp = cantor(b,);
mark[temp] = ;
nd1.pos = temp;
q.push(nd1);
while(!q.empty())
{
nd2 = q.front();
q.pop();
for(i=;i<;i++)
{
nd1.x = nd2.x + cx[i];
nd1.y = nd2.y + cy[i];
if(nd1.x>=&&nd1.x<&&nd1.y>=&&nd1.y<)
{
memcpy(nd1.b,nd2.b,sizeof(int)*);
exchange(nd1.b,nd1.x*+nd1.y,nd2.x*+nd2.y);
temp = cantor(nd1.b,);
nd1.pos = temp;
if(mark[temp]==) continue;
mark[temp] = ;
pre[temp] = nd2.pos;
if(cx[i]==)
{
if(cy[i]==) dir[temp] = 'l'; //因为是从目标状态开始搜索的,最后需要倒序输出,然后方向也应该是相反输出
else dir[temp] = 'r'; //dir[temp] = 'l' 的反方向
}
if(cy[i]==)
{
if(cx[i]==) dir[temp] = 'u'; //同上
else dir[temp] = 'd'; //同上
}
q.push(nd1);
}
}
}
} int main()
{
char str[];
int a[],b[]={,,,,,,,,}; //末状态,从末状态开始搜索
bfs(b,,); //预先搜索所有状态
while(~scanf("%s",str))
{
if(str[]=='x') a[]=;
else a[]=str[]-'';
int i;
for(i=;i<;i++)
{
scanf("%s",str);
if(str[]=='x') a[i]=;
else a[i]=str[]-'';
}
int temp = cantor(a,); //得到起始状态,然后回溯到末状态
if(!mark[temp]) //所有状态里面若没有起始状态,则为不可达
{
printf("unsolvable\n");
continue;
}
while(temp) //回溯过程
{
printf("%c",dir[temp]);
temp = pre[temp];
}
putchar();
}
return ;
}
hdu 1043 pku poj 1077 Eight (BFS + 康拓展开)的更多相关文章
- HDU - 1043 - Eight / POJ - 1077 - Eight
先上题目: Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 【HDU - 1043】Eight(反向bfs+康托展开)
Eight Descriptions: 简单介绍一下八数码问题:在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图: 1 2 3 4 5 6 7 8 在上图中,由于右下角位置是空的 ...
- Eight (HDU - 1043|POJ - 1077)(A* | 双向bfs+康拓展开)
The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...
- 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 4531 bfs/康拓展开
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4531 吉哥系列故事——乾坤大挪移 Time Limit: 2000/1000 MS (Java/Othe ...
- bnuoj 1071 拼图++(BFS+康拓展开)
http://www.bnuoj.com/bnuoj/problem_show.php?pid=1071 [题意]:经过四个点的顺逆时针旋转,得到最终拼图 [题解]:康拓展开+BFS,注意先预处理,得 ...
- 九宫重拍(bfs + 康拓展开)
问题描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...
- 8数码,欺我太甚!<bfs+康拓展开>
不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ...
随机推荐
- axel源码学习(1)——重要流程细节
前面一篇文章的流程太过于简单,基本没有触及到axel的核心,因此本文将要把axel中的几个重要的主要的操作流程单独弄出来看看,还是按照main函数的执行顺序来展开,略去错误处理之类的流程仅仅着眼于最重 ...
- Find security bugs学习笔记V1.0
Find security bugs学习笔记V1.0 http://www.docin.com/p-779309481.html
- linux 多核
posix threading programming beej's guide to unix ipc the gnu c library: virtual memory allocation an ...
- show status详解
Aborted_clients 某种原因客户程序不能正常关闭连接而导致失败的连接的数量.没有正常关闭 Aborted_connects 指出试图连接到MYSQL的失败的次数.这种情况在客户尝试用错误的 ...
- 【Fibonacci】BestCoder #28B Fibonacci
Fibonacci Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- Redis Cluster踩过的坑
Redis Cluster踩过的坑请参考如下链接:http://www.iteye.com/blogs/subjects/Redis_Cluster_Devops
- 【转】周末班LR笔记总结—新手入门必备
本来想上传文件的,上传半天没反应,只有这样了,图片不知道能显示不. 上午 学到2012.1.13 七天课 第一天(入门)二.三.四天(VUGEN脚本) 五天(Controller)六天(Analyse ...
- 【转】java.util.vector中的vector的详细用法
[转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...
- Exchanger, Changing data between concurrent tasks
The Java concurrency API provides a synchronization utility that allows the interchange of data betw ...
- Jquery方法大全
一.JQuery常用的方法 :(JQuery中90%都是方法,没有参数是获取,带参数是设置) $("#id").css('backgroundColor','blue'); .cs ...