HDU 3567 Eight II (A*)
2015-09-08 15:32
232 查看
题目链接:Eight II
解析:还是八数码问题,当然还是A*了,只不过这次要加上预处理才行。
先枚举出‘X’的位置,然后用前驱表保存所有情况
然后直接回溯就行了,不用再搜了。
AC代码:
解析:还是八数码问题,当然还是A*了,只不过这次要加上预处理才行。
先枚举出‘X’的位置,然后用前驱表保存所有情况
然后直接回溯就行了,不用再搜了。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <stack> using namespace std; struct Node{ char mz[3][3]; int x, y; Node(){} Node(char* str){ int xx = 0, yy = 0; for(int i=0; str[i]; i++){ mz[xx][yy] = str[i]; if(str[i] == 'X'){ x = xx; y = yy; } yy ++; if(yy == 3){ xx ++; yy = 0; } } } }start; int fac[]= {1,1,2,6,24,120,720,5040,40320}; int num[11]; int dir[4][2] = {1, 0, 0, -1, 0, 1, -1, 0}; char to_s[5] = "dlru"; int _hash(Node &a){ char s[11]; int ans = 0; for(int i=0; i<3; i++) for(int j=0; j<3; j++){ s[i*3+j] = a.mz[i][j]; int cnt = 0; for(int k=i*3+j-1; k>=0; k--) if(s[k] > s[i*3+j]) cnt ++; ans += fac[i*3+j]*cnt; } return ans; } char str[11], op[11][400000]; int pre[11][400000]; bool vis[400000]; void bfs(int x){ memset(vis, false, sizeof(vis)); memset(pre[x], -1, sizeof(pre[x])); queue<Node> q; q.push(start); vis[_hash(start)] = true; while(!q.empty()){ Node now = q.front(); q.pop(); int hnow = _hash(now); for(int i=0; i<4; i++){ Node tp = now; tp.x += dir[i][0]; tp.y += dir[i][1]; if(tp.x < 0 || tp.y < 0 || tp.x >= 3 || tp.y >= 3) continue; tp.mz[now.x][now.y] = tp.mz[tp.x][tp.y]; tp.mz[tp.x][tp.y] = 'X'; int htp = _hash(tp); if(vis[htp]) continue; vis[htp] = true; pre[x][htp] = hnow; op[x][htp] = to_s[i]; q.push(tp); } } } int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif // sxk start = Node("X12345678"); bfs(0); start = Node("1X2345678"); bfs(1); start = Node("12X345678"); bfs(2); start = Node("123X45678"); bfs(3); start = Node("1234X5678"); bfs(4); start = Node("12345X678"); bfs(5); start = Node("123456X78"); bfs(6); start = Node("1234567X8"); bfs(7); start = Node("12345678X"); bfs(8); int T, p; scanf("%d", &T); for(int kase=1; kase<=T; kase++){ scanf("%s", str); for(int i=0, j=0; str[i]; i++){ if(str[i] == 'X') p = i; else num[str[i]-'0'] = j++; } scanf("%s", str); for(int i=0; str[i]; i++){ if(str[i] == 'X') continue; str[i] = num[str[i]-'0'] + '1'; } start = Node(str); int hs = _hash(start); string ans = ""; while(hs != -1){ ans += op[p][hs]; hs = pre[p][hs]; } printf("Case %d: %d\n", kase, ans.size()-1); //有一个是起始位置,要减去 for(int i=ans.size()-2; i>=0; i--) putchar(ans[i]); //注意输出 puts(""); } return 0; }
相关文章推荐
- 数据结构之---C语言实现归并排序
- 关于一致/非一致代码段与TSS 关系的个人看法
- Eclipse For Android设置代码自动联想功能
- 华为机试测试-整数中二进制1的个数
- spring_150805_datasource
- Maven 手动添加 JAR 包到本地仓库
- IE兼容性
- thinking in programing
- plsql链接oracle Could not load "……\bin\oci.dll"异常
- Matlab cell函数
- Ubuntu 安装mysql和简单操作
- C++中未解之谜
- UML类图几种关系的总结
- Android 裁剪图片 aspectX aspectY outputX outputY的设置规则纠正
- Linux下查看和添加PATH环境变量
- 斯坦福大学iOS应用开发教程学习笔记(第二课) 计算器实现2 改进版
- iOS开发——项目篇—高仿百思不得姐
- (十一) android项目中退出应用程序工具类,直接用这个工具类可以很好地在任何地方退出应用程序
- Unity3D 导入脚本のAnimation动画切割
- xen安装(一)