题意:
给9个时钟的初始状态,和一些对某几个钟的操作,求最少经过几步能到目标状态(全指向12点)。
分析:
明显的广搜,但实现起来的细节要注意:1.因为要记录路径,所以要在整个程序执行过程中扩展出的节点在输出路径前不能销毁, 故采用静态内存分配的方法(开node[600000],用get_node()创建节点。2.queue<node>比queue<int>要多花1别的时间。
//poj 1166 //sep9 #include <iostream> #include <queue> using namespace std; char move[10][8]={"ABDE","ABC","BCEF","ADG","BDEFH","CFI","DEGH","GHI","EFHI"}; int vis[1000000],idx; int ans[10000]; struct NODE { int state,pre,move_used,idx; }node[600000]; queue<int> q; NODE get_node(int sta,int pre,int moves) { node[idx].state=sta; node[idx].pre=pre; node[idx].move_used=moves; node[idx].idx=idx; return node[idx++]; } int main() { int a[10],b[10],ini_state=0; idx=0; memset(vis,0,sizeof(vis)); while(!q.empty()) q.pop(); for(int i=0;i<9;++i) scanf("%d",&a[i]); for(int i=8;i>=0;--i) ini_state=ini_state*4+a[i]; NODE p=get_node(ini_state,-1,0); vis[p.state]=1; q.push(p.idx); int target_idx; while(!q.empty()){ int x=q.front();q.pop(); if(node[x].state==0){ target_idx=node[x].idx; break; } int tmp=node[x].state; for(int i=0;i<9;++i){ a[i]=tmp%4; tmp/=4; } for(int i=0;i<9;++i){ for(int j=0;j<9;++j) b[j]=a[j]; for(int j=0;move[i][j]!='\0';++j) b[move[i][j]-'A']=(a[move[i][j]-'A']+1)%4; int ns=0; for(int j=8;j>=0;--j) ns=ns*4+b[j]; if(vis[ns]==0){ NODE np=get_node(ns,node[x].idx,i+1); q.push(np.idx); vis[ns]=1; } } } int x=0; while(target_idx!=0){ ans[x++]=node[target_idx].move_used; target_idx=node[target_idx].pre; } for(int i=x-1;i>=0;--i) printf("%d ",ans[i]); return 0; }
时间: 2024-10-06 01:14:54