标签:
题意:给出 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",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\n",ans); 51 } 52 } 53 return 0; 54 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4346153.html