poj3278 Catch That Cow
阿新 • • 發佈:2018-04-27
大於等於 OS str 農場 bfs 廣度優先搜索 efi else queue
http://poj.org/problem?id=3278
題目大意:農場主約翰得知了一頭逃跑的母牛的行蹤,想立即抓住她。他從一個點開始,N(0≤N≤100000)在數軸上,牛點K(0≤K≤100000)在同一數軸。農夫約翰有兩種交通方式:步行和心靈運輸。
*行走:FJ可以在一分鐘內從任意點X移動到點X - 1或X + 1。
*傳送:FJ可以在一分鐘內從任何點X移動到點2。
如果奶牛不知道它的追求,根本不動,農夫約翰要多久才能取回它?
也就是說如果John所在位置大於等於母牛所在位置,那麽只能倒退直接得到最優解。如果John所在位置小於母牛所在位置,那麽每一個結點都有三個可選結點,分別是當前節點+1,-1,*2。
選取適當的剪枝函數,當當前結點越界時即<0或>100000時相應結點不進入隊列,當找到一個可行解(最優解)時,即到達了母牛的位置,直接返回最優解step[k]。
算法思想:隊列式分支限界法,以廣度優先搜索三叉樹,設置一個隊列q來存儲從John所在的位置開始入隊,然後出隊並開始拓展三個子結點(三個子節點入隊)。設置一個數組step[i]來記錄走到某位置的最少時間,並設置一個數組vis[i]來記錄是否到過某位置,如果到過表示前面有更優解,便可以舍棄相應子節點(不入隊列)。
Ps: 如果不了解STL queue容器的用法,可以百度。
1 #include<queue>//使用queue 容器 2 #include <iostream> 3 #include <cstring> 4 #define N 100001 5using namespace std; 6 int bfs(int n, int k) { 7 queue<int>q;//利用隊列模擬求解 8 int step[N];//到某位置的走的最少時間 9 bool vis[N]; 10 memset(vis, false, sizeof(vis)); 11 memset(step, 0, sizeof step); 12 int x, next; 13 step[n] = 0;//初始化在n時為0步 14 vis[n] = true;//標記訪問過 15 q.push(n);16 while (!q.empty()) { 17 x = q.front();//當前位置 18 q.pop(); 19 for (int i = 0; i < 3; i++) {//模擬三種情況 20 if (i == 0) next = x - 1; 21 else if (i == 1) next = x + 1; 22 else if (i == 2) next = x * 2; 23 if (next<0 || next>N) continue; 24 if (!vis[next]) {//如果訪問過 說明前面有更好的解 25 vis[next] = true; 26 q.push(next); 27 step[next] = step[x] + 1;//到next位置時的最少時間 28 } 29 if (next == k) return step[next];//到k時的最少時間 30 } 31 } 32 } 33 int main() { 34 int n, k; 35 cin >> n >> k; 36 if (n >= k) cout << n - k << endl; 37 else cout << bfs(n, k) << endl; 38 return 0; 39 }
poj3278 Catch That Cow