王道机试指南读后总结-4(有迷宫问题)

来源:互联网 发布:天津南开区淘宝城 编辑:程序博客网 时间:2024/05/29 18:57

搜索:



1.百鸡问题这种枚举问题注意的是有没有隐含条件减少枚举量,例如小鸡的个数可以用100-公鸡-母鸡得到而减少了循环层数。还有的是在第二层循环就可以母鸡的循环上限其实就是100-公鸡数2.BST走三维迷宫(广度优先搜索非常适合解决最优解问题)入口(0,0,0),出口(A-1,B-1,C-1),每分钟走一格,能否在T分钟走到出口。没格有无墙有墙2种。思路:a.要标记数组,搜索过的不再搜索b.将原本对路径的搜索转化为对状态的搜索,广度优先搜索即对状态间的相互转移构成的解答树进行的层次遍历。
//状态结构struct State{int x,y,z;int t;};int move[][3]={1,0,0,-1,0,0,0,1,0,0,-1,0,0,0,1,0,0,-1};  //移动数组bool mark[a][b][c]={0}; //标记是否走过bool wall[a][b][c]={0}; //标记是否有墙queue <State> s;  //状态队列time=BFS(a,b,c);int BFS(a,b,c){while(s.empty()!=true){ //状态树的层次遍历State now=s.front(),temp;s.pop();for(i=0;i<6;i++){temp.x=now.x+move[i][0];temp.y=now.y+move[i][1];temp.z=now.z+move[i][2];temp.t=now.t+1;               //新状态if(temp.t<0||temp.y<0||temp.z<0||temp.x>=a||temp.y>=b||temp.z>=c)  //新状态是否超出范围continue;if(mark[temp.x][temp.y][temp.z]==1)   //如果被搜索过,跳过continue; if(wall[temp.x][temp.y][temp.z]==1)   //如果有墙,跳过continue;s.push(temp);  //新状态符合进一步搜索的要求mark[temp.x][temp.y][temp.z]=1;  //标记if(temp.x==a-1&&temp.y==b-1&&temp.z==c-1)    //如果到了出口返回时间return temp.t;}}return -1;  //没有符合要求的,返回-1}

广度优先搜索几个关键字:
1.队列:为了扩展之前实现的状态,使用队列,将每次得到的状态依次放入队尾,每次取队头进行扩展。
2.标记:为了判断有效状态需要对状态进行标记。
3.状态扩展:尽可能扩展状态,并且先扩展先得出的状态,在解答树上的表现为我们层次遍历所有状态。


递归:

汉诺塔问题变形:每次移动必须是移到中间杆或者从中间杆移出,其他规则不变。

思路:考虑N个盘子从第一杆移到第三杆,等价于考虑N-1个盘子加一个最大盘子;
1.首先是N-1个盘子从第一杆到第三杆,然后加一步最大盘子到第二杆;
2.其次把N-1个盘子移到第一杆(等价于N-1个盘子从第一杆到第三杆),然后加一步最大盘子到第三杆;
3.最后把N-1个盘子移到第三杆;
这样设F(N)为把N个盘子从第一杆移到第三杆的移动次数,则F(N)=3*F(N-1)+2,F(1)=2;

long long hanoi(int num){if(num==1)return 2;else return 3*hanoi(num-1)+2;}




0 0
原创粉丝点击