POJ 1077 Eight
题意:经典的八数码=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的更多相关文章
- 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 ...
- Eight POJ - 1077 HDU - 1043 八数码
Eight POJ - 1077 HDU - 1043 八数码问题.用hash(康托展开)判重 bfs(TLE) #include<cstdio> #include<iostream ...
- HDU - 1043 - Eight / POJ - 1077 - Eight
先上题目: Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tota ...
- 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]*( ...
- 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 ...
- poj 1077 Eight(双向bfs)
题目链接:http://poj.org/problem?id=1077 思路分析:题目要求在找出最短的移动路径,使得从给定的状态到达最终状态. <1>搜索算法选择:由于需要找出最短的移动路 ...
- poj 1077 Eight (八数码问题——A*+cantor展开+奇偶剪枝)
题目来源: http://poj.org/problem?id=1077 题目大意: 给你一个由1到8和x组成的3*3矩阵,x每次可以上下左右四个方向交换.求一条路径,得到12345678x这样的矩阵 ...
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
- HDU 1403 Eight&POJ 1077(康拖,A* ,BFS,双广)
Eight Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
随机推荐
- Block、委托、回调函数原理剖析(在Object C语境)——这样讲还不懂,根本不可能!
开篇:要想理解Block和委托,最快的方法是搞明白“回调函数”这个概念. 做为初级选手,我们把Block.委托.回调函数,视为同一原理的三种不同名称.也就是说,现在,我们把这三个名词当成一回事.在这篇 ...
- POJ 3270 Cow Sorting(置换群)
题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...
- EXPRESS.JS再出发
那个那个MEAN的书,看得七七八八,有了大概,现在就要一样一样的加深记忆啦.. EXPRSS.JS的东东,网上有现成入门书籍: 第一期代码测试: var express = require('expr ...
- TopCoder SRM 633div1
250pts PeriodicJumping 题意:从起点开始,每次按找数组jump给定的长度,即jump[0], jump[1], jump[2].....jump[n-1], 向各个方向跳,跳 ...
- phpmyadmin导入大sql文件失败解决办法
摘自:http://www.xunway.com/info/post/499.asp 昨天小编的一个客户在在利用phpmyadmin导入大sql文件的时候,总是提示错误,反应给小编,小编也是第一次遇到 ...
- 61. Rotate List
题目: Given a list, rotate the list to the right by k places, where k is non-negative. For example:Giv ...
- UVa 10256 - The Great Divide 判断凸包相交
模板敲错了于是WA了好几遍…… 判断由红点和蓝点分别组成的两个凸包是否相离,是输出Yes,否输出No. 训练指南上的分析: 1.任取红凸包上的一条线段和蓝凸包上的一条线段,判断二者是否相交.如果相交( ...
- linux scp
scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令.linux的scp命令可以在linux服务器之间复制文件和目录. scp命令的用处: scp ...
- 【HDOJ】2774 Shuffle
1. 题目描述有长度为$n \in [1, 10^5]$的序列,表示一个打乱的循环排列,即每当$[1 \cdots n]$中的数字全部出现后,再重新产生一个随机的覆盖$[1 \cdots n]$的序列 ...
- 对mysql经常使用语句的详细总结
下面总结的知识点全是经常用的,全都是干货,好好收藏吧. /* 启动mysql */net start mysql /* 连接与断开服务器 */mysql -h 地址 -p 端口 -u 用户名 -p 密 ...