POJ3278农夫和牛(dfs)
Posted syyyyy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ3278农夫和牛(dfs)相关的知识,希望对你有一定的参考价值。
题目:
现有一农夫和一母牛,假设农夫和母牛都站在一条数轴上,农夫开始的位置为N,母牛的位置为K。农夫有三种行动方式,每行动一次需要一秒钟时间,假设农夫的现在的位置为X,他可以向前走一格到X+1,也可以向后走一格走到X-1,他还可以传送!一下子走到了2*X。那么我们的问题是,假设母牛不会动,农夫最少需要多少秒才能抓到母牛?
输入:
输入包括两个整数,用空格隔开,分别为N和K。其中0<=N,K<=100000。
输出:
一个整数T,代表农夫所需的最少时间。
分析:
若N=5,K=17,那么最后我们计算得到的应该是T=4。
1、全部往前走,一共是17-5=12步;
2、5×2=10 , 5→10→20→19→18→17;
3、最优方案,5→4→8→16→17。
根据DFS,将农夫在每一步所走的策略都列举出来,生成一棵三叉正则完全树。用队列Queue存储这些结果,根据队列先进先出的特性,最先找到农夫到达奶牛的结果所花费的时间便是最短的时间。
(DFS一般都用队列存储结果)
但是,由于广度优先搜索要列出所有的结果,因此容易超时。要对广搜做一定的优化,即剪枝处理(去掉一些没必要存储的结果)
本题优化如下:
1.当农夫的位置为0的时候,他只能往前走1。
2.当农夫的位置大于K时,他只能往后走1 。
3.如果某个位置农夫已经走过,那么农夫不用再走到该位置。
源代码:
//三叉搜索树的顺序 #include <iostream> #include <queue> #include <cstring> using namespace std; int num[10000005]; int vis[10000005]; int n, k, y ; queue<int> q; void bfs( ) { q.push( n ); num[n] = 0; while( q.size() && y != k ) { if( y == k ) break; y = q.front(); q.pop(); if( y - 1 >= 0 && vis[y + 1] == 0 ) { q.push( y - 1 ); num[y - 1] = num[y] + 1 ; vis[y - 1] = 1; } if( y + 1 < 100000 && vis[y+1] == 0 ) { q.push( y + 1 ); num[y + 1] = num[y] + 1 ; //记录步数 vis[y + 1] = 1 ; //标记该位置已经走过 } if( y * 2 < 100000 && vis[y * 2] == 0 ) { q.push( y * 2); num[ y * 2] = num[y] + 1; vis[y * 2] = 1; } // cout << y << endl; } } int main(int argc, const char * argv[]) { cin >> n; cin >> k; memset( num, 0, sizeof(num)); memset( vis, 0, sizeof(vis)); while( !q.empty() ) q.pop(); bfs(); cout <<num[y] << endl; //最终,y == k }
以上是关于POJ3278农夫和牛(dfs)的主要内容,如果未能解决你的问题,请参考以下文章