http://acm.hdu.edu.cn/showproblem.php?pid=2717
从N到K,N可以N+1,N-1,N*2这三种方式前进,找到K为止!至少需要多少次前进!
题目挺水的,一刻钟敲完后,测试啊数据都正确,MD总是报Runtime Error(ACCESS_VIOLATION)这是什么鸟啊???
看了别人的报告后,发现自己的BFS写的如此之烂... ...
#include<iostream>
#include<algorithm>
using namespace std;
#include<queue>
const int MAX = 200001;
int from,go;
int step = 0;
bool findit =false;
bool vis[MAX];
queue<int>q;
queue<int>tempq;
int tempnum=0;
void bfs(){
if(findit)return ;
step++;
while(q.size()!=0){
tempnum = q.front();
if(tempnum==go){findit=true;break;}
q.pop();
if(tempnum-1>=0&&!vis[tempnum-1])
{tempq.push(tempnum-1);vis[tempnum-1]=true;}
if(!vis[tempnum+1]){
vis[tempnum+1]=true;
tempq.push(tempnum+1);
}
if(!vis[tempnum*2]){
vis[tempnum*2]=true;
tempq.push(2*tempnum);
}
}
q = tempq;
bfs();
}
int main(){
while(cin>>from>>go){
step=0;
findit=false;
memset(vis,false,sizeof(vis));
q.push(from);
vis[from]=true;
bfs();
cout<<step-1<<endl;
while(q.size())q.pop();
while(tempq.size())tempq.pop();
}
return 0;
}
受DFS的影响,把BFS也写成递归式的了,好囧,看了一个顺序式的,学习一下,以后不再那么二了....
看了一下别人的报告,发现大体思路一样,但实现的手法不同,我是通过一个bool vis[]数组来记忆该坐标是否检查过,最终移动了多少步靠的是一个int step值来确定,相当于搜索树一层一层的遍历搜索,遍历一层step++,但是有个缺点是,遍历第i曾的时候,pop()出来的数不能直接加到该层的队尾,还得需要一个辅助的队列来暂时存放,最后在拷贝回去,这样就保证了,q[]队列中的元素一直都是同一层次的。
而下面这份儿报告实现起来更好一些,他用一int a []数组来代替我的vis[],而且另一作用是存放的数值为step值,q[]队列中存放坐标(这点肯定一样),这样就可以pop()出来一个数,就分别往后面塞进三个数,a[i] 在根据上一坐标值加1即可。
//“横向”广搜,用到队列.
#include <iostream>
#include <queue>
using namespace std;
const long N=200001;//因为输入的数n,k最大值为100000,
//但有一个2*k位置要存储,所以要将N设置到两倍最大值。
int main()
{
queue<long> q;//建立队列q
long n,k,a[N];//数组记录前进的步数
while(cin>>n>>k)//从n开始去搜索k。
{
memset(a,0,sizeof(a));//将数组a每个元素赋0
if(n==k)
{
cout<<a[n]<<endl;
continue;// 如果输入的n==k,直接输出
}
q.push(n);//否则,n压入队列
while(!q.empty())
{
int c=q.front();//取队头
if(c==k)
{
cout<<a[c]<<endl;//如果==k,则输出数组在该位置的值
while(!q.empty())//并且销毁队列
q.pop();
break;
}
a[c]++;//如果!=k,让该位置的数组自增一
q.pop();
//搜索与对头相关的三个数,且判断是否满足条件
if(c-1>=0&&a[c-1]==0)
{
q.push(c-1);//该位置压入队列
a[c-1]=a[c];//将对头数组值赋予该位置数组
}
if(c+1<=2*k&&a[c+1]==0)
{
q.push(c+1);
a[c+1]=a[c];
}
if(2*c<=2*k&&a[2*c]==0)
{
q.push(2*c);
a[2*c]=a[c];
}
}
}
return 0;
}