北大ACM原創題目 母牛的故事(距離推理)

2021-10-17 04:26:31 字數 1554 閱讀 6871

母牛的故事

從前有乙個農夫,他的名字叫做約翰。他養了很多很多頭母牛。突然有一天,乙隻調皮的母牛走丟了,農夫要盡快的抓住她,不然她就又跑掉了!現在我們將問題簡單化。假設農夫和母牛都站在一條數軸上,農夫開始的位置為n,母牛的位置為k。

約翰有三種行動方式,每行動一次需要一秒鐘時間,假設農夫的現在的位置為x,他可以向前走一格到x+1,也可以向後走一格走到x-1,他還可以傳送!一下子走到了2*x。

那麼我們的問題是,假設母牛不會動,農夫最少需要多少秒才能抓到母牛?

輸入:輸入包括兩個整數,用空格隔開,分別為n和k。其中0<=n,k<=100000。

輸出:乙個整數t,代表農夫所需的最少時間。

這裡我們給出一組資料,假設n=5,k=17,那麼最後我們計算得到的應該是t=4.

怎麼計算得來的呢?假設我們採用全部往前走的策略,那麼我們一共要走17-5=12步。這個策略明顯是不對的。因為我們一開始就讓5×2=10,這樣可以省去很多步驟,那麼我是不是只要乘得越多得到的步數就越少呢?
5→10→20→19→18→17

當農夫的位置變為20後,這個時候他能做的只有往後走,所以我們有這樣乙個看似更優的策略,一直乘2直到x大於k,然後再算出往後走的步數。這樣的策略算出來是5(一共走了5步),這樣的策略明顯跟正確的答案不一樣。實際上我們有更優的策略!
5→10→9→18→17

#include

#include

//用系統提供的佇列

using namespace std;

int n,k;

//當前狀態,x為農夫當前的位置,t為農夫走過的次數

struct point

;//用於標記該位置農夫是否走過

bool vis[

200050];

//題目說n<=100000,所以我們要把陣列定義成比100000*2大一點點的大小,防止陣列越界!(有興趣的可以用思考下為什麼)

intmain()

//如果往後走不是0,並且往後走的那個位置沒有被走過,那麼我們就把往後的情況加入到佇列

if(temp.x-

1>=

0&&vis[temp.x-1]

==0)//往前走的情況

if(temp.x==0

)//乘2的情況

if(temp.x==0)}

return0;

}

實際上,我們直接讓計算機幫我們計算出每一種情況就可以了。我們知道一開始的位置是5,那麼我們可以把所有情況都列舉一遍,即試一下往前走1往後走1或乘2。然後我們再對得到的三種情況4,6,10繼續重複上面的步驟得到5,3,8,7,5,12,11,9,20 。這樣我們不斷地得到乙個越來越大的數列,最後只要看看這個數列裡面有沒有k,就代表我們是否到達了k,這個時候我們只要輸出我們重複了多少次這個步驟,就是答案了。
分析:

當農夫的位置為0的時候,他只能往前走1。

當農夫的位置大於k時,他只能往後走1 。

如果某個位置農夫已經走過,那麼農夫不用再走到該位置。

題目 1004 遞迴 母牛的故事

題目 1004 遞迴 母牛的故事 時間限制 1sec 記憶體限制 128mb 提交 57063 解決 17498 題目描述 有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?輸入輸入資料由多個測試例項組成,每個測試例...

題目 1004 遞迴 母牛的故事

有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?輸入輸入資料由多個測試例項組成,每個測試例項佔一行,包括乙個整數n 0輸出 對於每個測試例項,輸出在第n年的時候母牛的數量。每個輸出佔一行。樣例輸入 245 0樣例輸...

45 題目 1004 遞迴 母牛的故事

時間限制 1sec 記憶體限制 128mb 提交 50680 解決 15534 題目描述 有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?輸入 輸入資料由多個測試例項組成,每個測試例項佔一行,包括乙個整數n 0輸出...