我只是做了一点微小的工作,比如看了大神的代码然后加了注释,大神的原博客http://www.cnblogs.com/suncoolcat/p/3339508.html
// // main.cpp // POJ1184 // // Created by 韩雪滢 on 10/23/16. // Copyright © 2016 韩雪滢. All rights reserved. // /*总体思路: * 原密码与最终密码逐个比较,如果不相同就停止比较 *建立树,树的根节点是原密码 *树的一级子节点是父节点在分别进行6种操作生成的不同密码:代码是将生成的密码按顺序加入到queue中 */ #include <iostream> #include <map> #include <string> #include <queue> using namespace std; struct point { int step; string s; }; string e; map<string,int> my; queue<point> q; int BFS(point st) { //ss[6]里存的是当前光标所在的string的索引值的ASC码,即ss[ss[6]-'0']为当前光标所在的位置的值 point t,tt; string ss; int i; while(!q.empty()) q.pop(); q.push(st); my[st.s]=1; while(!q.empty()) { t=q.front(); q.pop(); for(ss=t.s,i=0;i<6;i++) if(ss[i]!=e[i]) break; if(i==6) return t.step; //t对于下面进行的6个操作来说是不变的,所以tt.step=t.step+1相同 ss=t.s; swap(ss[0],ss[ss[6]-'0']);//Swap0: //检查经过swap0后是否匹配 if(!my.count(ss)) //map::count(要搜索的key),返回匹配的key的个数,因为map中key的唯一性,所以返回的是0/1 { //不匹配,把经过swap0的string加入到my中,并设置当前的按键次数为上一次按键后生成的新string的案件个数+1 tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } ss=t.s; swap(ss[5],ss[ss[6]-'0']); //Swap1 if(!my.count(ss)) { tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } ss=t.s; if(ss[ss[6]-'0']!='9'&&ss[ss[6]-'0']!=e[ss[6]-'0']) ss[ss[6]-'0']+=1; //Up: if(!my.count(ss)) { tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } ss=t.s; if(ss[ss[6]-'0']!='0'&&ss[ss[6]-'0']!=e[ss[6]-'0']) ss[ss[6]-'0']-=1;//Down: if(!my.count(ss)) { tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } ss=t.s; if(ss[6]-'0'!=0)//left { if(ss[6]!='5') //0 1 2 3 4位置相同才能移动光标 { if(ss[ss[6]-'0']==e[ss[6]-'0']) ss[6]-=1; } else ss[6]-=1; } if(!my.count(ss)) { tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } ss=t.s; if(ss[6]-'0'!=5)//Right { if(ss[6]!='0') //1 2 3 4位置相同才能移动光标 { if(ss[ss[6]-'0']==e[ss[6]-'0']) ss[6]+=1; } else ss[6]+=1; } if(!my.count(ss)) { tt.s=ss; tt.step=t.step+1; q.push(tt); my[ss]=1; } } return 0; } int main(int argc, char *argv[]) { point st; while(cin>>st.s>>e) { my.clear();//清空map中所有的元素 st.s+='0';//光标初始位置为0 st.step=0; cout<<BFS(st)<<endl; } return 0; }