cf 295 div 2 B (bfs)

题意:给出 n、m 两数,可以对 n 进行两种操作 减一或者乘二,操作过程中 n 必须保证非负,问使 n 变为 m 至少需要几步操作。

这是我练水题的时候做到的,题目不难,只是我 bfs 一直没怎么用过比较不熟练,RE 了两发,就整理了这题。

首先,若 n==m ,那么步骤数就是 0 ,而若 n > m ,n 进行乘二的操作就会使 n 离 m 更远,所以必然是一直减一,于是步骤数就是 n -m ;

若 n < m , 此时由于中间的步骤并不确定,就可以用 bfs 搜索,但是由于使用数组记录某个数字是否被访问过,当数组并没有刻意开很大的时候,就必须先判断对 n 进行操作后的值是否在数组范围内,而不能先判断其数组值,我就因此 RE 了两次,还是需要注意的。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 
 6 bool f[20005];
 7 int b[20005];
 8 
 9 int main(){
10     int n,m;
11     while(scanf("%d%d",&n,&m)!=EOF){
12         if(n>=m)printf("%d
",n-m);
13         else{
14             memset(f,0,sizeof(f));
15             memset(b,0,sizeof(b));
16             f[n]=1;
17             b[n]=0;
18             queue<int>q;
19             while(!q.empty()){
20                 q.pop();
21             }
22             q.push(n);
23             int ans=0;
24             while(!q.empty()){
25                 int a=q.front();
26                 q.pop();
27                 if(a<m){
28                     if(!f[2*a]){
29                         q.push(a*2);
30                         f[a*2]=1;
31                         b[a*2]=b[a]+1;
32                         if(a*2==m){
33                             ans=b[a*2];
34                             break;
35                         }
36                     }
37                 }
38                 if((a-1)>0){
39                     if(!f[a-1]){
40                         q.push(a-1);
41                         f[a-1]=1;
42                         b[a-1]=b[a]+1;
43                         if(a-1==m){
44                             ans=b[a-1];
45                             break;
46                         }
47                     }
48                 }
49             }
50             printf("%d
",ans);
51         }
52     }
53     return 0;
54 }
View Code
原文地址:https://www.cnblogs.com/cenariusxz/p/4346153.html