您的位置:首页 > 其它

HDU 2717||POJ 3278 BFS入门(理解原理)

2016-06-01 16:37 435 查看

HDU 2717

Catch That Cow

Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 11677 Accepted Submission(s): 3617



[align=left]Problem Description[/align]
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer
John has two modes of transportation: walking and teleporting.

* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute

* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

[align=left]Input[/align]
Line 1: Two space-separated integers: N and K

[align=left]Output[/align]
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

[align=left]Sample Input[/align]

5 17


[align=left]Sample Output[/align]

4

HintThe fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.


[align=left]Source[/align]
USACO 2007 Open Silver

[align=left]Recommend[/align]
teddy | We have carefully selected several similar problems for you: 2102 1372 1240 1072 1180

DFS入门题目,但数据量较大。注意开数组的大小,容易RE。
北大郭炜老师课件中的源码:
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int N,K;
const int MAXN = 100000;
int visited[MAXN+10];  //判重标记,visited[i] = true表示i已经扩展过
struct Step
{
int x;  //位置
int steps;  //到达x所需的步数
Step(int xx,int s):x(xx),steps(s) { }
};
queue<Step> q;  //队列,即Open表
int main()
{
cin >> N >> K;
memset(visited,0,sizeof(visited));
q.push(Step(N,0));
visited
= 1;
while(!q.empty())
{
Step s = q.front();
if( s.x == K )   //找到目标
{
cout << s.steps <<endl;
return 0;
}
else
{
if( s.x - 1 >= 0 && !visited[s.x-1] )
{
q.push(Step(s.x-1,s.steps+1));
visited[s.x-1] = 1;
}
if( s.x + 1 <= MAXN && !visited[s.x+1] )
{
q.push(Step(s.x+1,s.steps+1));
visited[s.x+1] = 1;
}
if( s.x * 2 <= MAXN &&!visited[s.x*2]  )
{
q.push(Step(s.x*2,s.steps+1));
visited[s.x*2]  = 1;
}
q.pop();
}
}
return 0;
}
自己写的代码:

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

int main()
{
int s,e;
while(cin>>s>>e){
queue<int> a;
bool y[100006];
memset(y,0,sizeof(y));
if(s>=e)
{
cout<<s-e<<endl;
continue;
}
int ans=1;
a.push(s);
y[s]=1;
a.push(-999999);
while(1)
{
int x=a.front();
if(x==-999999){
a.push(-999999);
ans++;
a.pop();
continue;
}
if(x-1>=0&&!y[x-1]){
if(x-1==e){cout<<ans<<endl;break;}
else{a.push(x-1);y[x-1]=1;}
}
if(x+1<=100000&&!y[x+1]){
if(x+1==e){cout<<ans<<endl;break;}
else{a.push(1+x);y[1+x]=1;}
}
if(x*2<=100000&&!y[2*x]){
if(x*2==e){cout<<ans<<endl;break;}
else{a.push(2*x);y[2*x]=1;}
}
a.pop();
}
}
}


参考自:点击打开链接
把队列转化为数组:
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

int main(){
int s,e;
int a[200005];//队列
int b[200005];//记录距离

while(cin>>s>>e){
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
int x=0;
int i=0;
a[0]=s;
b[s]=1;
while(1){
if(a[i]==e)
{
cout<<b[a[i]]-1<<endl;
break;
}
if(a[i]+1<=100000&&!b[a[i]+1]){
a[++x]=a[i]+1;b[a[i]+1]=b[a[i]]+1;
}
if(a[i]*2<=100000&&!b[a[i]*2]){
a[++x]=a[i]*2;b[a[i]*2]=b[a[i]]+1;
}
if(a[i]-1>=0&&!b[a[i]-1]){
a[++x]=a[i]-1;b[a[i]-1]=b[a[i]]+1;
}
i++;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: