当前位置: 代码迷 >> 综合 >> poj 3221 Diamond Puzzle 反向bfs
  详细解决方案

poj 3221 Diamond Puzzle 反向bfs

热度:0   发布时间:2024-01-19 05:37:40.0

分析:

简单的bfs,但要注意因为输入cases很多,对每个初始状态都搜一遍会超时,其实可以从终止状态反向搜一遍,对搜到的每个状态打表存下即可。

代码:

//poj 3221
//sep9
#include <iostream>
#include <queue> 
using namespace std;
int n;
int fac[]={1,1,2,6,24,120,720,5040,40320}; 
int vis[10000],g[10000];
int pos[8][8];
struct NODE
{int s[9];int loc;int status;
};int cantor(int s[])  
{  int sum=0;  for(int i=0;i<7;++i){  int cnt=0;  for(int j=i+1;j<7;++j)  if(s[i]>s[j])  ++cnt;  sum+=cnt*fac[7-i-1];  }  return sum;       
}  void bfs(NODE start)
{queue<NODE> open;NODE cur,nxt;memset(vis,0,sizeof(vis));memset(g,-1,sizeof(g));vis[start.status]=1;g[start.status]=0;open.push(start);while(!open.empty()){cur=open.front();open.pop();int cur_zero_pos=cur.loc;for(int i=1;i<=pos[cur_zero_pos][0];++i){int nxt_zero_pos=pos[cur_zero_pos][i];nxt=cur;swap(nxt.s[cur_zero_pos],nxt.s[nxt_zero_pos]);nxt.loc=nxt_zero_pos;nxt.status=cantor(nxt.s);if(vis[nxt.status]==0){open.push(nxt);g[nxt.status]=g[cur.status]+1;vis[nxt.status]=1;}}} 
}int main()
{int cases;pos[0][0]=3,pos[0][1]=2,pos[0][2]=4,pos[0][3]=6;pos[1][0]=2,pos[1][1]=2,pos[1][2]=6;pos[2][0]=3,pos[2][1]=0,pos[2][2]=1,pos[2][3]=3;pos[3][0]=2,pos[3][1]=2,pos[3][2]=4;pos[4][0]=3,pos[4][1]=0,pos[4][2]=3,pos[4][3]=5;pos[5][0]=2,pos[5][1]=4,pos[5][2]=6;pos[6][0]=3,pos[6][1]=0,pos[6][2]=1,pos[6][3]=5;NODE ncur;for(int i=0;i<7;++i)ncur.s[i]=i;ncur.loc=0;ncur.status=cantor(ncur.s);bfs(ncur);scanf("%d",&cases);while(cases--){char ch[16];int s[16];scanf("%s",ch);for(int i=0;i<7;++i)s[i]=ch[i]-'0';int cantor_value=cantor(s);printf("%d\n",g[cantor_value]);}	return 0;	
}