题意:经典的八数码=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. crontab 不能执行git命令问题备忘

    这问题够隐蔽,折腾了近两个小时. 命令 git checkout tagname 手工执行都正常 但在crontab运行时发现分支一直切不过去. 后来告诉是crontab默认的 path  设置和系统 ...

  2. POJ 3270 Cow Sorting(置换群)

    题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...

  3. hdu 4111 Alice and Bob 博弈论

    这里有2种方法: 方法一:求SG函数 sg[i][j]:i表示1的个数,j表示合并操作的步数. 这共有4种操作: 1.消除一个1: 2.减掉一个1: 3.合并2个1: 4.把1合并到另外不是1中. 代 ...

  4. 2013 ACM-ICPC长沙赛区全国邀请赛——A So Easy!

    这题在比赛的时候不知道怎么做,后来看了别人的解题报告,才知道公式sn=(a+sqrt(b))^n+(a-sqrt(b))^n; 具体推导 #include<iostream> #inclu ...

  5. 保障视频4G传输的流畅性,海康威视摄像头相关设置

    我们目前的rtsp视频解决方案如下: 摄像头<---------->NVR(通过4G上传)<---------->easydarwin<---------->自己的 ...

  6. linux shell 命令学习(1) du- estimate file space usage

    du - estimate file space usage , 计算文件的磁盘大小 语法格式: du [OPTION] ... [FILE] 描述: 汇总每个文件的磁盘大小, 递归汇总目录的大小, ...

  7. 喵星人教你记 HTTP 状态码

    记忆HTTP状态码是有一些困难的,因为状态码很多且很难记忆.GirlieMac,也就是Tomomi Imura利用她巧妙的构思,PS了一系列的HTTP状态信息.在你看过这些图片之后,你绝对可以记住一些 ...

  8. linux 查看某一端口的占用情况

    查看某一端口的占用情况: lsof -i:端口号,例如查看端口21是否被占用 lsof -i: 实例:查看端口是否被占用,如果被占用结束掉该端口 [root@localhost splunk]# ls ...

  9. HttpServletRequest接口实例化的使用

    HttpServletRequ接口的使用和jsp内置对象的request对象非常类似,request对象其实 就是HttpServletRequest接口的一个实例,不过气实例化的过程是自动的,无须自 ...

  10. Servlet中Service方法

    doGet方法只能处理Get方式提交的请求,doPost则可以处理Post方式提交的请求, 一种既可以处理Get方式又可以处理Post方式的提交的请求,它就是Service方法. service方法用 ...