您的位置:首页 > 其它

POJ3278---bfs

2014-07-27 16:04 225 查看
道题蛮简单,了解了基本的搜搜算法就可以解决这道题,题意大致就是给你两个数N和K,N每次可以进行+1,-1,*2的运算, 问你最少几次N可以变成K,这个问题我们如果用dfs的话,就会出问题,因为最优解永远是距离N最近的变换得到的那个值,所以这里我们可以用到bfs,但是由于这个时候我们需要统计的是达到最优解时的最少次数,即需要我们在树形解空间中找到目标解在这棵树种的层数,所以我们需要一个标号数组deep[] (和网络流的标号法蛮像),下一层的标号是上层标号加1,然后我们bfs的过程是:先将初始状态入队,然后对初始状态下的每一个分支进行判断(这道题里就是对n进行的+1,-1,*2进行判断),如果满足到达最终状态的条件,则搜索结束,否则将当前状态的分支状态入队,这样当当前层的所有状态搜搜完毕而没有发现可行解,那么下一层的状态会出队,接受检验知道找到那个解...

代码
bool visited[max];
int deep[max];
int N,K;
int bfs(){
int count = 0;
queue<int> q;
q.push(N);
memset(deep,0,sizeof(deep));
memset(visited,false,sizeof(visited));
visited
= true;
deep
= 0;
int s = 1;
while(!q.empty()){
int tp = q.front();
q.pop();
visited[tp] = true;
if(tp == K)
break;
else{
int ans1 = tp + 1;
int ans2 = tp - 1;
int ans3 = tp * 2;
if(ans1 <= 100000&&!visited[ans1]){
deep[ans1] = deep[tp] + 1;
q.push(ans1);
visited[ans1] = true;
}
if(ans2 >= 0&&!visited[ans2]){
deep[ans2] = deep[tp] + 1;
q.push(ans2);
visited[ans2] = true;
}
if(ans3 <= 100000&&!visited[ans3]){
deep[ans3] = deep[tp] + 1;
q.push(ans3);
visited[ans3] = true;
}
}
}
return deep[K];
}
int main() {
cin>>N>>K;
cout<<bfs()<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: