HDU 3567 Eight II (搜索)
2016-08-26 13:38
357 查看
题意:给出两个状态的八数码,问输出第一个状态转移到第二个状态的满足以下条件的方案
1.步骤最少
2.字典序最小
如果直接进行转移,有几个很明显的问题,一时间不足,二如果双向BFS字典序不好处理,但是由于这道题的特殊性,我们只需要从一个状态转移到另一个状态,假设第一个输入为初状态,可以归纳为九类:012345678,102345678,120345678,123045678,123405678,123450678,123456078,123456708,123456780,分别作为初状态,第二个输入无非就是根据这些状态进行映射转移,由康托展开可以知道最多为3600000个状态,直接预处理出这九个状态的方案解决问题
1.步骤最少
2.字典序最小
如果直接进行转移,有几个很明显的问题,一时间不足,二如果双向BFS字典序不好处理,但是由于这道题的特殊性,我们只需要从一个状态转移到另一个状态,假设第一个输入为初状态,可以归纳为九类:012345678,102345678,120345678,123045678,123405678,123450678,123456078,123456708,123456780,分别作为初状态,第二个输入无非就是根据这些状态进行映射转移,由康托展开可以知道最多为3600000个状态,直接预处理出这九个状态的方案解决问题
#include<cstring> #include<string> #include<iostream> #include<queue> #include<cstdio> #include<algorithm> #include<map> #include<cstdlib> #include<cmath> #include<vector> //#pragma comment(linker, "/STACK:1024000000,1024000000"); using namespace std; #define INF 0x3f3f3f3f #define maxn 3600000 char d[]={"dlru"}; int dir[][5]={{1,0},{0,-1},{0,1},{-1,0}}; struct node { int step; int index; int cant; char g[11]; }t[maxn]; int fa[10][maxn]; int ans[10][maxn]; int vis[10][maxn]; int fac[]= {1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800}; ///0~8 int cantor(char ss[]) { int s[10]; for(int i=0; i<9; i++) s[i]=ss[i]-'0'; int sum=0; for(int i=0; i<9; i++) { int num=0; for(int j=i+1; j<9; j++) if(s[j]<s[i]) num++; sum+=(num*fac[9-i-1]); } return sum+1; } bool judge(int x,int y) { return x>=0&&x<3&&y>=0&&y<3; } int que[maxn]; void bfs(int k,char s[]) { int l=0,r=-1; int cant=cantor(s); que[++r]=cant; memcpy(t[cant].g,s,sizeof t[cant].g); t[cant].index=k; fa[k][cant]=-1; t[cant].cant=cant; vis[k][cant]=1; t[cant].step=1; while(l<=r) { int f=que[l++]; int x=t[f].index/3; int y=t[f].index-3*x; for(int i=0;i<4;i++) { int _x=x+dir[i][0]; int _y=y+dir[i][1]; if(judge(_x,_y)) { node temp=t[f]; swap(temp.g[temp.index],temp.g[_x*3+_y]); temp.cant=cantor(temp.g); if(vis[k][temp.cant]) continue; vis[k][temp.cant]=temp.step+1; ans[k][temp.cant]=i; fa[k][temp.cant]=f; temp.index=_x*3+_y; temp.step++; t[temp.cant]=temp; que[++r]=temp.cant; } } } } void print(int k,int st,int ed) { if(ed==st) return ; print(k,st,fa[k][ed]); printf("%c",d[ans[k][ed]]); } int main() { char str[20]; strcpy(str,"012345678"); bfs(0,str); strcpy(str,"102345678"); bfs(1,str); strcpy(str,"120345678"); bfs(2,str); strcpy(str,"123045678"); bfs(3,str); strcpy(str,"123405678"); bfs(4,str); strcpy(str,"123450678"); bfs(5,str); strcpy(str,"123456078"); bfs(6,str); strcpy(str,"123456708"); bfs(7,str); strcpy(str,"123456780"); bfs(8,str); int T; int ca=1; scanf("%d",&T); while(T--) { char str1[20],str2[20]; int num[20]; memset(num,0,sizeof num); int px,cant1,py,cant2; scanf("%s%s",str1,str2); for(int i=0,j=1; i<9; i++) { if(str1[i]=='X') str1[i]='0',px=i; if(str1[i]!='0') num[str1[i]-'0']=j,str1[i]=j+'0',j++; } for(int i=0;i<9;i++) { if(str2[i]=='X') str2[i]='0'; str2[i]=num[ str2[i]-'0' ]+'0'; } cant1=cantor(str1); cant2=cantor(str2); printf("Case %d: %d\n",ca++,vis[px][cant2]-1); print(px,cant1,cant2); puts(""); } return 0; }
相关文章推荐
- HDU 3567 Eight II
- HDU 3567 Eight II
- HDU 3567 Eight II 八数码(2)
- HDU 3567 Eight II
- HDU 3567 Eight II
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
- HDU-3567 Eight II
- HDU 3567 Eight II 预处理+bfs+hash
- HDU-3567 Eight II
- hdu 3567 Eight II 八数码 双向BFS
- hdu 3567 Eight II (bfs+康托展开+预处理)
- HDU 3567 - Eight II
- HDU 3567 Eight II 八数码(2)
- hdu 1072 Nightmare BFS搜索(可重走)
- HDU 2446(搜索题,二分)
- HDU 1969(搜索题,二分)
- HDU 1251(搜索题,典型的字典树问题)
- hdu 1015 Safecracker 暴力搜索
- HDU 2899(搜索题,二分)
- hdu 1242 Rescue BFS搜索