POJ3278

来源:互联网 发布:58同城网络兼职打字员 编辑:程序博客网 时间:2024/06/06 03:29

本学期选了学校的算法课程,P大研究生的算法课程难度不小(PS:对于我这种菜狗),加上本科没有学过算法,更是有点被虐的感觉,所以平时更要多加练习

没事的时候就去做题。

POJ3278

,2总时间限制: 
2000ms 
内存限制: 
65536kB
描述

农夫知道一头牛的位置,想要抓住它。农夫和牛都位于数轴上,农夫起始位于点N(0<=N<=100000),牛位于点K(0<=K<=100000)。农夫有两种移动方式:

1、从X移动到X-1或X+1,每次移动花费一分钟
2、从X移动到2*X,每次移动花费一分钟

假设牛没有意识到农夫的行动,站在原地不动。农夫最少要花多少时间才能抓住牛?
输入
两个整数,N和K
输出
一个整数,农夫抓到牛所要花费的最小分钟数
样例输入
5 17
样例输出
4
思路:
这个是典型的广搜问题,因为要求的是最短的路径,类似的有迷宫问题找路之类的,广搜一般要用一个结构体(对象)来代表每一个状态,用一个队列queue来记录先后的访问顺序,并且一定要注意状态的边界条件和状态的转换关系(本期中是位置变化的转换关系),农夫可以向前找(+1 表示),也可以向后找(-1 表示),也是跨距离找(* 2表示)
注意的地方是  1,广搜的时候每次访问完队头的节点后要把它pop出去
2, DFS 和BFS 一般实现时都要用一个大的visited 数组表示是否已经访问过了。
3,多种情形扩展时,不能用 else if 而是用并列的 if (DFS也一样),否则搜索空间会减小,一些状态不会被枚举到,else if 直接跳过剩下的cases,一些点就没有入队。 这是一个隐藏的坑。
#include <iostream>#include <cstring>#include <queue>using namespace std;const int MAXN = 100000;int visited[MAXN+10]; //判重标记,visited[i] = true表示i已经扩展过int N,K;struct step1{int x;int steps;step1(int xx,int ss):x(xx),steps(ss){}};queue<step1> q;/*注意的地方是 广搜的时候每次访问完队头的节点后要把它pop出去。多种情形扩展时,不能用if else 而是用并列的 if (DFS也一样),否则搜索空间会减小。 */int main(){cin>>N>>K;memset(visited,0,sizeof(visited));q.push(step1(N,0));visited[N]=1;while(!q.empty()){step1 curS = q.front();if(curS.x==K){cout<<curS.steps<<endl;return 0;}if(curS.x-1>=0&& !visited[curS.x-1]){q.push(step1(curS.x-1,curS.steps+1));visited[curS.x -1] = 1;} if(curS.x+1<=MAXN && !visited[curS.x+1]){q.push(step1(curS.x+1,curS.steps+1));visited[curS.x +1] = 1;} if(curS.x*2<=MAXN && !visited[curS.x*2]){q.push(step1(curS.x*2,curS.steps+1));visited[curS.x *2] = 1;}q.pop(); //每次出队一个结点 }}
希望坚持下去!!!每天3题!!!

原创粉丝点击