题意:经典的八数码=3=

3*3的格子,里面有1~8这8个数字,还有一个空格x,移动空格的位置,直到移到1~8按顺序排好,输出移动的序列。

解法:看到题果断写了个广搜……然后T了……百度了一下说广搜虽然慢了点但是也是可以过的嘛……默默看了眼自己代码……唔……好像他们都不是用string路径的……

实在懒得改了,学个新做法吧,哦吼吼吼这个A*看起来很神奇啊……学一下学一下

600ms+过了……嗯……跟别人广搜一个时间啊……_(:з」∠)_实在不想改记路径的方法啊……

A*我觉得就是一个更聪明的广搜……每个状态的权值为每个数到最终状态的曼哈顿距离之和加上已走过的步长,用优先队列维护……

还有就是每个状态序列可以转换成一个排列的id……涨姿势了0v0

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long using namespace std; int fac[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };
int order(vector <int> v) {
int i, j, temp, num;
num = 0;
for (i = 0; i < 8; i++) {
temp = 0;
for (j = i + 1; j < 9; j++) {
if (v[j] < v[i])
temp++;
}
num += fac[v[i] -1] * temp;
}
return num;
}
bool vis[400000];
int dir1[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1};
char dir2[] = "udlr";
struct node
{
vector <int> v;
string path;
node(vector <int> tv, string tpath)
{
v = tv;
path = tpath;
}
node() {}
bool operator < (const node &tmp) const
{
int sum1 = 0, sum2 = 0;
for(int i = 0; i < 9; i++)
sum1 += abs((v[i] - 1) / 3 - i / 3) + abs((v[i] - 1) % 3 - i % 3);
for(int i = 0; i < 9; i++)
sum2 += abs((tmp.v[i] - 1) / 3 - i / 3) + abs((tmp.v[i] - 1) % 3 - i % 3);
return sum1 + path.size() > sum2 + tmp.path.size();
}
};
string bfs(vector <int> st)
{
memset(vis, 0, sizeof vis);
vis[order(st)] = 1;
priority_queue <node> q;
q.push(node(st, ""));
while(!q.empty())
{
node tmp = q.top();
if(order(tmp.v) == 0) return tmp.path;
q.pop();
int sx, sy;
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
if(tmp.v[i * 3 + j] == 9)
{
sx = i;
sy = j;
}
for(int i = 0; i < 4; i++)
{
int tx = sx + dir1[i][0], ty = sy + dir1[i][1];
if(tx < 0 || tx > 2 || ty < 0 || ty > 2) continue;
swap(tmp.v[tx * 3 + ty], tmp.v[sx * 3 + sy]);
int id = order(tmp.v);
if(!vis[id])
{
vis[id] = 1;
q.push(node(tmp.v, tmp.path + dir2[i]));
}
swap(tmp.v[tx * 3 + ty], tmp.v[sx * 3 + sy]);
}
}
return "unsolvable";
}
int main()
{
char input[2];
while(~scanf("%s", input))
{
vector <int> v;
if(input[0] == 'x')
v.push_back(9);
else
v.push_back(input[0] - '0');
for(int i = 0; i < 8; i++)
{
scanf("%s", input);
if(input[0] == 'x')
v.push_back(9);
else
v.push_back(input[0] - '0');
}
int sum = 0;
for(int i = 1; i < 9; i++)
for(int j = 0; j < i; j++)
if(v[i] != 9 && v[j] != 9 && v[i] < v[j]) sum++;
if((sum & 1) == 0)
cout << bfs(v) << endl;
else
puts("unsolvable1");
}
return 0;
}

  

POJ 1077 Eight的更多相关文章

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

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

  2. HDU 1043 & POJ 1077 Eight(康托展开+BFS | IDA*)

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

  3. Eight POJ - 1077 HDU - 1043 八数码

    Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...

  4. HDU - 1043 - Eight / POJ - 1077 - Eight

    先上题目: Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

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

  6. 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 ...

  7. poj 1077 Eight(双向bfs)

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

  8. poj 1077 Eight (八数码问题——A*+cantor展开+奇偶剪枝)

    题目来源: http://poj.org/problem?id=1077 题目大意: 给你一个由1到8和x组成的3*3矩阵,x每次可以上下左右四个方向交换.求一条路径,得到12345678x这样的矩阵 ...

  9. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  10. HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)

    Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

随机推荐

  1. git安装及使用

    一.安装 1.从http://code.google.com/p/msysgit/下载Git-1.8.4-preview20130916.exe,并安装. 2.新建git目录,右键选择Git Bash ...

  2. POJ2632Crashing Robots

    做模拟题做的我直接睡着了,题并不难,就是一个细心的问题,有一些细节问题注意了就差不多了,代码写的精美的一般找错误也好找一些,应该学着些好看的代码 #include<cstdio> #inc ...

  3. hdu 1376 Octal Fractions

    刚开始做这题时,用的是0.75[8]=(7/8+5/64)[10]这个,但是总是WA…………无语了…… 后来看别人的解题报告,知道了另外一个就是0.75[8]=((5/8+7)/8)[10],从低位向 ...

  4. 如何在linux系统下对文件夹名有空格的文件夹进行操作

    http://www.2cto.com/os/201409/335119.html 在Windows操作系统中可以轻易地创建\移动\删除文件夹名带有空格的文件夹, 而在linux则需要进行一些特殊的处 ...

  5. cojs 奈特 题解报告

    才知道knight念奈特,而不念科耐特 这个题显然是一个数据结构题目,我搬运的CF上的题 CF的题解好长超长哒,而且可以在线,但是并不能看懂 于是自己想了一个一种做法A掉了,唯一的缺陷就是做法有些繁琐 ...

  6. JavaWeb项目开发案例精粹-第2章投票系统-001设计

    1.项目结构 2.数据库设计 # MySQL-Front 5.0 (Build 1.0) /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE */; /*!40101 SET ...

  7. POJ 水题若干

    POJ 3176 Cow Bowling 链接: http://poj.org/problem?id=3176 这道题可以算是dp入门吧.可以用一个二维数组从下向上来搜索从而得到最大值. 优化之后可以 ...

  8. ubuntu 乱码 改为英文

    http://878045653.blog.51cto.com/2693110/735654 解决方法: 改成全英文环境来解决 方格 乱码 : 用vim配置语言环境变量 vim / etc/envir ...

  9. 使用 GIT 获得Linux Kernel的代码并查看,追踪历史记录

    Linux kernel  的官方 GIT地址是: http://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git 可以从这个地 ...

  10. MySQL学习笔记二

    Ø function 函数 函数的作用比较大,一般多用在select查询语句和where条件语句之后.按照函数返回的结果, 可以分为:多行函数和单行函数:所谓的单行函数就是将每条数据进行独立的计算,然 ...