poj1077八数码问题——境界二
来源:互联网 发布:网站存在sql注入漏洞 编辑:程序博客网 时间:2024/05/29 10:06
八数码之八重境界http://www.cnblogs.com/goodness/archive/2010/05/04/1727141.html
关键在于利用康托展开判重
发现自己模拟的队列比STL中queue快
#include<stdio.h>#include<string.h>#include<string>#include<algorithm>#include<iostream>#include<set>#include<map>#include<queue>#include<stack>#include<vector>#include<math.h>#include<stdlib.h>#define M 400000using namespace std;struct stu{ char s[20]; int pos;}st,ed,dl[M];struct pa{ int fa; char c;}path[M];int mark[M];int jc[12];int h[4]={-1,0,1,0};int z[4]={0,1,0,-1};char fa[]={"urdl"},pstr[M];void getjc()//阶乘 { int i,j,k; jc[0]=1; for(i=1;i<12;i++) jc[i]=jc[i-1]*i;}int getkt(char s[20])//康托展开 { int i,j,k,len,an[20],ans=0; getjc(); len=strlen(s); memset(an,0,sizeof(an)); for(i=0;i<len;i++)//获得当前未出现的比他小的数,即它右边有几个比他小的数 for(j=0;j<i;j++) { if(s[j]>s[i]) an[j]++; } for(i=0;i<len;i++)//康托公式运算 { ans+=an[i]*jc[len-i-1]; } return ans; }void prin(char s[20]){ int i,j; for(i=0;i<9;i++) { if(i%3==0) puts(""); printf("%c ",s[i]); }}void getnikc(int len,int xu)//逆康托 { int i,j,k; int xs[20],js[20]; char s[20]; getjc(); for(i=len-1,j=0;i>=0;i--,j++)//辗转相除,得到an { xs[j]=xu/jc[i]; if(xu!=0) xu=xu%jc[i]; js[i]=1; } for(i=0;i<len;i++)//找剩下子集中的第xs[i]大元素 { int t=0; for(j=0;j<len;j++) { t+=js[j]; if(t>xs[i]) { s[i]='0'+j; js[j]=0; break; } } } s[len]='\0'; prin(s);}int judge(int x,int y){ return (x>=0&&x<3&&y>=0&&y<3);}int bfs(){ int i,j,k,r,f,x,y,t; char s[20]; char c; memset(mark,0,sizeof(mark)); r=f=0; dl[0]=st; k=getkt(st.s); mark[k]=1; path[k].fa=k;// printf("st kt %d\n",k); while(r<=f) { k=getkt(dl[r].s); if(k==ed.pos) return k; for(i=0;i<4;i++) { stu nw; strcpy(nw.s,dl[r].s); int p=dl[r].pos; x=p/3; y=p%3; // printf("qian x=%d,y=%d %d\n",x,y,p); x=x+h[i]; y=y+z[i]; // printf("hou x=%d,y=%d %d\n",x,y,x*3+y); if(judge(x,y)) { t=x*3+y; c=nw.s[p]; nw.s[p]=nw.s[t]; nw.s[t]=c; nw.pos=t; t=getkt(nw.s); if(mark[t]==0) { dl[++f]=nw; path[t].fa=k; path[t].c=fa[i]; mark[t]=1; } } } r++; } return -1;}int main(){// freopen("1077.in","r",stdin); // freopen("1077.out","w",stdout); int i,j,k; char c; for(i=0;i<9; ) { scanf("%c",&c); if(c == 'x') { st.s[i]='0'; st.pos=i; i++; } else if(c>='0'&&c<='9') { st.s[i] = c; i++; } else continue; } st.s[9]='\0';// printf("aaa %s %d\n",st.s,st.pos);// while(1) {/* scanf("%s",st.s); for(i=0;i<9;i++) { if(st.s[i]=='x') { st.pos=i; st.s[i]='0'; } }*/ strcpy(ed.s,"123456780"); ed.pos=getkt(ed.s);// printf("ed.p %d\n",ed.pos); int ans=bfs(); if(ans==-1) { puts("unsolvable"); } else { i=0; // getnikc(9,ans); while(ans!=path[ans].fa) { // printf("\nans %d fa %d\n",ans,path[ans].fa); // printf("%c",path[ans].c); pstr[i++]=path[ans].c; ans=path[ans].fa; // getnikc(9,ans); } pstr[i]='\0'; // puts(""); reverse(pstr,pstr+i); puts(pstr); } } return 0;}/*23415x768*/
- poj1077八数码问题——境界二
- poj1077八数码问题——境界五(A*)
- poj1077八数码问题——境界六(IDA*)
- POJ1077 八数码问题
- poj1077 hdu1043 Eight 八数码问题
- Poj1077/HDU1043(A*搜索)八数码问题
- POJ1077(经典的八数码问题)
- POJ1077八数码问题哈希,bfs
- 八数码与IDA*问题 HDU1043&&POJ1077
- hdu1043八数码问题——境界三
- POJ1077(8数码问题)
- 菜鸟系列——八数码八境界
- POJ1077、HDU1043 Eight 八数码问题:双向BFS、A*
- 【POJ1077】Eight 八数码问题,解题报告+思路+代码
- 【康托展开+状压BFS】poj1077 Eight(八数码问题)
- 八数码难题 hdu1043/ poj1077
- POJ1077 HDU1043 Eight 八数码第四境界 双向广搜 康托展开 逆康托
- POJ1077&HDU1043 Eight 八数码第八境界 IDA* hash 康托展开 奇偶剪枝
- Visual States in WPF 4.0
- Java Annotation
- 剪断的翅膀,如何起飞
- Android中如何使用ViewPager实现类似laucher左右拖动效果
- Web Service的简单用法
- poj1077八数码问题——境界二
- 代码重构调试问题集合
- F7显示物料时带树状菜单
- Android:Activity和Fragment交互、Fragment控件UI升级相关内容
- CMake使用教程
- 进程间通信方式总结(windows 和linux)
- 点击视图中的图片拖动位置
- NO One
- mysql两个字段相同的表联合查询(union的使用)