Eight
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 37738   Accepted: 15932   Special Judge

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as:

 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

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle

 1  2  3

x 4 6

7 5 8

is described by this list:

 1 2 3 x 4 6 7 5 8 

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr

Source

 
年轻人的第一道A* 答案可能多解
我的这个程序输入样例输入得到的输出是 ldruullddrurdllurrd
跟样例输出不一样 搞的我郁闷了半天
 
注意方向的选取 还有位置的选择
它是
1 2 3
4 5 6
7 8 9
 
康拓展开
类似哈希 给定一个排列组合的数  如123456789 怎么去判定有没有遍历过这个数 可以用康拓展开 八数码问题有9位 直接开1e9的数组可能爆内存 并且有很多数字是用不到的 因为每个数字只出现一次 可能会有123456789 但是绝对不会出现123456788 以此类推 这样浪费了很多空间
由此引出康拓展开 由这个数是第几小的数来作表示 对N个不同的数的排列组合 一共有N!种排列组合 他们的大小都不一样 所以只需要N!的空间就足够存放所有的状态
要注意自己定义的康拓的范围
其中 递增顺序排列是最小的数 即123456789  987654321是最大的数
我这里写的是goal = 1,  所以 cantor是返回v+1避免出现0, 要是 goal = 0, 则cantor返回v就行了 以此类推
记忆方法: 只要记住顺序排列是最小的 它的v是最小的 在以下代码片中要让return v+1 等于1 容易知道下划线部分应该填  ar[j] < ar[i]
int contor(int ar[]) {
int v = ;
for (int i = ; i < ; i++) {
int num = ;
for (int j = i + ; j < ; j++) {
if (_______) num++;
}
v += num * fac[ - i];
}
return v + 1;
}
 
还有个注意点是曼哈顿距离不算x点
短即是正义 我短我骄傲
 #include <stdio.h>
#include <queue>
#include <algorithm>
using namespace std;
int fac[];
int dx[] = {-, , , };
int dy[] = {, , , -};
char d[] = {'u','d','r','l'};
const int goal = , maxv = 4e5;
bool vis[maxv];
int pre[maxv];
char dir[maxv];
int dish(int ar[]) {
int dis = ;
for (int i = ; i < ; i++) {
if (ar[i] == ) continue;
int v = ar[i] - ;
int rx = i / , ry = i % ;
int x = v / , y = v % ;
dis += abs(x - rx) + abs(ry - y);
}
return dis;
}
int contor(int ar[]) {
int v = ;
for (int i = ; i < ; i++) {
int num = ;
for (int j = i + ; j < ; j++) if (ar[j] < ar[i]) num++; v += num * fac[ - i];
}
return v + ;
}
struct node {
int g, h, f, sta, xpos;
int s[];
void init() {
g++; h=dish(s); f=h+g; sta=contor(s);
}
bool operator < (const node x)const {
return f > x.f;
}
};
priority_queue<node> q;
bool Astar(node now) {
fill(vis, vis + maxv, );
while (!q.empty()) q.pop();
now.g = -;
now.init();
q.push(now);
pre[now.sta] = -;
vis[now.sta] = ;
while (!q.empty()){
now = q.top(); q.pop();
if (now.sta == goal) return true;
int xpos = now.xpos;
int x = xpos / , y = xpos % ;
for (int i = ; i < ; i++) {
int tx = x + dx[i];
int ty = y + dy[i];
if (tx < || ty < || tx >= || ty >= ) continue;
int newp = tx * + ty;
node tp = now;
tp.xpos = newp;
swap(tp.s[newp], tp.s[xpos]);
tp.init(); if (vis[tp.sta]) continue;
vis[tp.sta] = ;
pre[tp.sta] = now.sta;
dir[tp.sta] = d[i];
q.push(tp);
}
}
return false;
}
void Print(int sta) {
if (pre[sta] == -) return;
Print(pre[sta]);
printf("%c", dir[sta]);
}
int main() {
fac[] = ;
for (int i = ; i < ; i++) fac[i] = i * fac[i - ];
char str[];
while (gets(str)) {
int cnt = ;
node now;
for (int i = ; str[i]; i++) {
if (str[i] == ' ') continue;
if (str[i] == 'x') {
now.xpos = cnt;
now.s[cnt++] = ;
}
else
now.s[cnt++] = str[i] - '';
}
if (Astar(now)) Print(goal);
else printf("unsolvable");
printf("\n");
}
return ;
}
 

1077 Eight的更多相关文章

  1. hihocode 1077 : RMQ问题再临-线段树

    #1077 : RMQ问题再临-线段树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到:小Hi给小Ho出了这样一道问题:假设整个货架上从左到右摆放了N种商品,并 ...

  2. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  3. LightOJ::1077 -----奇妙的最大公约数

    题目:http://www.lightoj.com/volume_showproblem.php?problem=1077 题意:在平面上, 给出两个点的坐标 例如:(x, y) 其中x, y 都是整 ...

  4. 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]*( ...

  5. 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: 1000 ...

  6. 九度OJ 1077 最大序列和 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1077 题目描述: 给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T的“序列和”. 对 ...

  7. hihocoder 1077线段树

    http://hihocoder.com/problemset/problem/1077 #include <bits/stdc++.h> using namespace std; #de ...

  8. poj 1077 Eight(双向bfs)

    题目链接:http://poj.org/problem?id=1077 思路分析:题目要求在找出最短的移动路径,使得从给定的状态到达最终状态. <1>搜索算法选择:由于需要找出最短的移动路 ...

  9. UVa 536 Tree Recovery | GOJ 1077 Post-order (习题 6-3)

    传送门1: https://uva.onlinejudge.org/external/5/536.pdf 传送门2: http://acm.gdufe.edu.cn/Problem/read/id/1 ...

  10. PAT 1077 Kuchiguse

    1077 Kuchiguse (20 分)   The Japanese language is notorious for its sentence ending particles. Person ...

随机推荐

  1. git-commit Angular规范

    commit message的格式 每次提交,Commit message 都包括三个部分:Header,Body 和 Footer. <type>(<scope>): < ...

  2. Maven 插件打包部署项目

    clean install -Dmaven.test.skip=true:打包工具 clean package  

  3. ZYNQ DMA驱动及测试分析

    之前没有接触过DMA驱动.不了解它的原理,稍作学习先总结下dma驱动步骤: 1. 申请DMA中断. 2. 申请内存空间作为src和dts的空间. 3. 注册设备注册节点 4. 将申请到的src和dst ...

  4. SQL语句全解,非常棒!

    链接自W3school非常详细的SQL教程 http://www.w3school.com.cn/sql/index.asp

  5. GNOME 系统设置

    详细的GNOME系统设置全文,参见这里. 以下摘录使用到的部分. 1. 在任务栏上显示日期或周几(二选一).秒数 $ gsettings set org.gnome.desktop.interface ...

  6. 微信小程序<swiper-item>标签中传入多个数组型数据的方法(小程序交流群:604788754)

    在<swiper-item>中用for循环传入多个成对不同数据时的实现方法. 效果如下: 遍历实现方法:wxss省略: wxml中代码: <!--导航部分轮播图--> < ...

  7. 关于sql的查询操作记录

    1.--读取库中的所有表名 select name from sysobjects where xtype='u'  --读取指定表的所有列名 select name from syscolumns  ...

  8. Unity录音

    上周做过Unity录音,(不知道的可以到网上查找一下,代码挺多的),不过只能录制麦克风的声音,项目需要同时录制背景音和麦克风传进去的声音,经过探索,现已可以录制: 首先需要知道,即使用电脑录音,想录制 ...

  9. spring boot 连接多个数据源

    在springboot中有需要连接多个数据源的情况. 首先配置文件application.properties中添加两个数据源连接字符串 mybatis.type-aliases-package=co ...

  10. FX-玩列表

    list = []while True: meus = ("1.查看","2.添加","3.删除","0.退出") pr ...