这里可以用bfs进行解决,dfs直接超时。要注意的是在bfs搜索过程中需要清晰地处理好“时间”的运算(题目是每走一次需要1minute),基本不会有太大的问题。
PS:这好像是我第一次用bfs进行解题,小白一个,多多见谅。
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MAXN = 100005;
int vis[MAXN], N, K, flag;
int dd(int k, int i) {
if (i == 0) return k - 1;
if (i == 1) return k + 1;
return 2 * k;
}
void bfs() {
int time = 1, newp = 0, oldp = 1;//time表示步数,newp、oldp分别表示队列中两种元素的个数
queue<int> Q;
//在队列中的元素使用“新”、”旧“进行分层,每当”旧“元素用完,说明这一层不能到达目的地,需要搜索下一层
//”新“元素是在“旧”元素的基础上进行扩充的,即对应题目中,所有“下一步”的集合,是在“当前一步”的基础上进行扩充的
Q.push(N);//把起始点放队列中
vis[N] = 1;//起始点以经“走过了”
while (!Q.empty()) {
int k = Q.front();//取出“当前位置”,然后对当前位置进行搜索符合要求的“下一步”放到队列中,作为下一次搜索的基础
Q.pop();
for (int i = 0; i < 3; i++) {
int x = dd(k, i);
if (x == K){//到达终点,从bfs算法上理解可以知道,现在就是最短路
flag = 1;
break;
}
if (x >= 0 && x <= MAXN - 5 && vis[x] == 0) {
vis[x] = 1;
Q.push(x);
newp++;
}
}
if (flag == 1) {
cout << time << endl;
break;
}
if (--oldp == 0) {
oldp = newp;
newp = 0;
time++;
}
}
}
int main() {
while (cin >> N >> K) {
if (N == K) {
cout << "0" << endl;
continue;
}
if (K < N) {
cout << N - K << endl;
continue;
}
flag = 0;
memset(vis, 0, sizeof(vis));
bfs();
}
return 0;
}