【BFS 康拓 A*】HDU
来源:互联网 发布:amd游戏优化档案 编辑:程序博客网 时间:2024/09/15 12:15
Problem Description
给你一个3*3的数组,让你变为1 2 3 4 5 6 7 8 x,x只能上下左右和旁边的交换位置,让你求出操作步骤。
代码:正常想法就是正常的BFS,BFS肯定要记录状态,标记状态,用正常的方法记录这个数组的状态,很大。所以用康拓展开(枚举全排列,九个数362880种情况),知道如何记录状态了,但是如果正常的BFS跑,情况太多,肯定会超时,所以得有目的性的跑,所以得用A星,h代表当前状态到目标状态估计的步骤(代价),g代表已经走了几步了。
#include<bits/stdc++.h>using namespace std;int vis[400000];int Hash[9];int xx[5] = {0, 1, -1, 0};int yy[5] = {1, 0, 0, -1};char ch[5] = {"rdul"};struct node{ int g, h; int state;//康拓展开 int num[9];//对应的状态 int pos;//x的下标 string step; //最小堆的优化队列 bool operator < (const node &b) const { if(h == b.h) return g > b.g; else return h > b.h; }};int kt(int a[])//求康拓展开{ int num = 0; int ans = 0; for(int i = 0; i < 9; i++) { for(int j = i + 1; j < 9; j++) if(a[i] > a[j]) num++;//求逆序队 ans += num * Hash[8 - i]; num = 0; } return ans;}int nx(int a[])//求逆序对,去掉x也就是0,一定是偶数,不是偶数没有结果{ int num = 0; for(int i = 0; i < 8; i++) { for(int j = i + 1; j < 9; j++) if(a[i] > a[j] && a[i] && a[j]) num++; } return num;}int dj(int a[])//最小代价{ int i, j; int ans = 0; for(i = 0; i < 3; i++) { for(j = 0; j < 3; j++) { //(a[i * 3 + j] - 1) / 3 是该值对应的目标行 (a[i * 3 + j] - 1) % 3 是该值对应的目标列 //相当于行和列下标。例如7 行是 2 列 是 0 ans += abs(i - (a[i * 3 + j] - 1) / 3) + abs(j - (a[i * 3 + j] - 1) % 3); } } return ans;}void Bfs(node u){ node v; memset(vis, 0, sizeof(vis)); int x, y; u.g = 0;//一开始没移动所以是0 u.h = dj(u.num);//到目标状态的步骤 u.state = kt(u.num);//求当前状态的康拓展开 vis[u.state] = 1;//然后标记当前状态 priority_queue<node> q; q.push(u); while(!q.empty()) { u = q.top(); q.pop(); if(u.state == 46233) // 40320+5040+720+120+24+6+2+1 { cout << u.step << endl;//达到目标状态输出操作步骤 return ; } int x1 = u.pos / 3, y1 = u.pos % 3;//行,列 坐标 for(int i = 0; i < 4; i++) { x = x1 + xx[i]; y = y1 + yy[i]; if(x >= 0 && y >= 0 && x < 3 && y < 3) { v = u; swap(v.num[x * 3 + y], v.num[u.pos]);//交换位置 v.state = kt(v.num); if(!vis[v.state])//如果该状态没有标记过 { vis[v.state] = 1;//标记 v.g++;//步骤+1 v.pos = x * 3 + y;//转换一维下标 v.h = dj(v.num);//求当前到目标的步骤 v.step = v.step + ch[i];//记录操作步骤 q.push(v); } } } }}int main(){ char s[2]; int i; Hash[0] = 1;//康拓展开映射 for(i = 1; i < 9; i++) { Hash[i] = Hash[i - 1] * i; } while(~scanf("%s", s)) { node u; if(s[0] == 'x') { u.num[0] = 0; u.pos = 0; } else u.num[0] = s[0] - '0'; for(i = 1; i < 9; i++) { scanf("%s", s); if(s[0] == 'x') { u.num[i] = 0; u.pos = i; } else { u.num[i] = s[0] - '0'; } } if((nx(u.num) & 1)) printf("unsolvable\n"); else { Bfs(u); } } return 0;}
阅读全文
0 0
- 【BFS 康拓 A*】HDU
- HDU 2102 A计划 BFS
- 【hdu】 A计划 (BFS)
- hdu 2102 A计划 BFS
- HDU 2102 A计划(BFS)
- hdu 2102 A计划 (bfs)
- Hdu 2102 A计划 [Bfs]
- HDU 2102 A计划 BFS
- HDU-a strange lift-BFS
- HDU 2102--A计划【BFS】
- HDU 2102 A计划 BFS
- hdu 2102 A计划(bfs)
- hdu 2102 A计划 BFS
- hdu 2102 A计划(bfs)
- HDU 2102 A计划(BFS)
- hdu 2102 A计划 BFS
- HDU 2102:A计划【bfs】
- hdu A计划 (BFS)
- Cakephp 执行主要流程
- C语言之结构体学习笔记
- Linux 用户组及文件权限操作
- 英文文档 的 学习
- Spring定时任务的几种实现
- 【BFS 康拓 A*】HDU
- springMVC 中获取session方法
- CakePHP FAQ(常见问题)整理
- 整数划分(递归)
- Go Tracing Roadmap
- io流 的简单回顾
- IO复习
- jsp登陆验证码
- Linux_FastDFS 安装笔记