最近练习一组搜索题
题目地址:poj 3278
题目大意: 给你一个数n 你可以+1,-1,*2,怎么用最少的步骤数达到给定的k,如果没有这样的方案输出-1;
用图论的理论搜索出一条路径即可
先看代码:
#include<iostream>
#include<queue>
#include<cstring>
#include<string>
using namespace std;
#define max 100005
int cnt[max];
int visit[max];
int n,k;
queue<int> q;
int bfs()
{
int cur,next;
cnt[n]=0;
visit[n]=1;
q.push(n);
cur=n;
while(!q.empty())
{ cur=q.front();
q.pop();
for(int i=0;i<3;i++)
{
if(i==0) next=cur-1;
else if(i==1) next=cur+1;
else next=cur*2;
if(next<0||next>=max) continue;
if(!visit[next])
{
q.push(next);
cnt[next]=cnt[cur]+1;
visit[next]=1;
}
if(next==k) return cnt[next];
}
}
return -1;
}
void init()
{
memset(cnt, 0,sizeof(cnt));
memset(visit,0,sizeof(visit));
}
int main()
{
init();
cin>>n>>k;
if(n>=k)
cout<<n-k<<endl;
else
{
cout<<bfs()<<endl;
}
}
重点解释一下为什么bfs求出的是最短路径,也许一开始会有疑惑 ,我们对一个节点cnt赋值的时候,怎么保证这个是最小的?
换句话说,只要赋值了,它一定是有这条通路的,但是如果之前有一个比较大的cnt[previous] 把它连累了怎么办~? 而且visit被标记为1 不会再用最小值进行更新了
额,实际上关注一下赋值序列就好了,这个层数序列一定是个不减序列 比如12233344 ,于是从访问的时间撮来说 不可能有这样的情况发生,那么就保证了最小性。