分析:
简单的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; }
时间: 2024-10-25 08:06:11