poj1077双向宽搜——境界四

来源:互联网 发布:如何优化网站页面 编辑:程序博客网 时间:2024/06/08 02:42

第一次写双向宽搜,比单向快很多。

要点:在判重的时候要注意对方是否已经到达。

#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,cdl[M],zdl[M];struct pa{int fa;char c;}cpath[M],zpath[M];int cmark[M],zmark[M];int jc[12];int h[4]={-1,0,1,0};int z[4]={0,1,0,-1};char fa[4][2]={'u','d','r','l','d','u','l','r'},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;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;}int judge(int x,int y){return (x>=0&&x<3&&y>=0&&y<3);}void getpath(int kt){int i=0,zd,bg;bg=kt;zd=getkt(st.s);while(bg!=zd){pstr[i++]=cpath[bg].c;bg=cpath[bg].fa;}pstr[i]='\0';reverse(pstr,pstr+i);printf("%s",pstr);//printf("\nc->z\n");bg=kt;zd=getkt(ed.s);while(bg!=zd){printf("%c",zpath[bg].c);bg=zpath[bg].fa;}puts("");}int bbfs(){int i,j,k;int cf,cr,zf,zr,x,y,t;cf=cr=zf=zr=0;char c;memset(cmark,0,sizeof(cmark));memset(zmark,0,sizeof(zmark));zdl[0]=ed;cdl[0]=st;k=getkt(ed.s);zmark[k]=1;k=getkt(st.s);cmark[k]=1;while(cr<=cf&&zr<=zf){k=cf;for(cr;cr<=k;cr++){int kt=getkt(cdl[cr].s);if(zmark[kt]==1){return kt;}for(i=0;i<4;i++){stu nw;strcpy(nw.s,cdl[cr].s);int p=cdl[cr].pos;x=p/3;y=p%3;x+=h[i];y+=z[i];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(cmark[t]==0){cdl[++cf]=nw;cpath[t].fa=kt;cpath[t].c=fa[i][0];cmark[t]=1;}} }}k=zf;for(zr;zr<=k;zr++){int kt=getkt(zdl[zr].s);if(cmark[kt]==1){return kt;}for(i=0;i<4;i++){stu nw;strcpy(nw.s,zdl[zr].s);int p=zdl[zr].pos;x=p/3;y=p%3;x+=h[i];y+=z[i];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(zmark[t]==0){zdl[++zf]=nw;zpath[t].fa=kt;zpath[t].c=fa[i][1];zmark[t]=1;}}}}}return -1;} int main(){getjc();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++;}       elsecontinue;     }st.s[9]='\0';strcpy(ed.s,"123456780");ed.pos=8;int ans=bbfs();if(ans==-1){puts("unsolvable");}else{getpath(ans);}return 0;}


 

原创粉丝点击