題目網址: POJ -- 3278ios
人的狀態每次有三種變化方式可選,題目問的又是「最少」的步數,因此用寬度優先搜索(BFS)就能夠解決。算法
由於一個點老是能在入隊列的第一時間進入隊列,因此在找到最終目標的時候用的步數是最少的。spa
在寫寬搜算法的過程須要注意的一點就是「判重」,即入過隊列的元素不可再次進入隊列。 事實上,若是不在元素入隊列的第一時間打上標記的話會有更嚴重的問題出現,內存溢出或者超時錯誤均可能因爲沒有判重致使。code
對於這道題目,不用擔憂時間問題,由於每一個點只進入一次隊列而且被處理一次,一共N個點,算法的複雜度不會超出O(N)的。隊列
#include <cstdio> #include <queue> #include <cstring> #include <iostream> using namespace std; const int maxn = 100000; int dist[maxn+10]; queue<int> q; int bfs(int N, int K) { q.push(N); dist[N] = 0; while(!q.empty()) { int X = q.front(); q.pop(); if(X == K) return dist[X]; if(X-1 >= 0 && dist[X-1] < 0) { q.push(X-1); dist[X-1] = dist[X] + 1; } if(X+1 <= maxn && dist[X+1] < 0) { q.push(X+1); dist[X+1] = dist[X] + 1; } if(X*2 <= maxn && dist[X*2] < 0) { q.push(X*2); dist[X*2] = dist[X] + 1; } } return -1; /// 實際上不存在這種狀況 } int main() { int N, K; cin >> N >> K; memset(dist, -1, sizeof(dist)); cout << bfs(N, K) << endl; return 0; }