網易筆試編程-飢餓的小易

題目描述:
小易總是感覺飢餓,所以作爲章魚的小易經常出去尋找貝殼吃。最開始小易在一個初始位置x_0。對於小易所處的當前位置x,他只能通過神祕的力量移動到 4 * x + 3或者8 * x + 7。因爲使用神祕力量要耗費太多體力,所以它只能使用神祕力量最多100,000次。貝殼總生長在能被1,000,000,007整除的位置(比如:位置0,位置1,000,000,007,位置2,000,000,014等)。小易需要你幫忙計算最少需要使用多少次神祕力量就能吃到貝殼。
輸入描述:
輸入一個初始位置x_0,範圍在1到1,000,000,006
輸出描述:
輸出小易最少需要使用神祕力量的次數,如果使用次數使用完還沒找到貝殼,則輸出-1
輸入例子:
125000000
輸出例子:
1
算法分析:
利用隊列實現廣度搜索,遍歷所有的可能性。利用容器map來映射小易所在的位置和到該位置小易所用的神祕力量次數。爲了保證map容器容量的有限性,小易所在的位置用距離總數對1,000,000,000,007的餘數來表示。因爲位置用餘數表示,所以必然會出現重複,所以在編碼的時候,需要將重複的位置去除,去除辦法就是在得到新位置後先判斷該位置是否已在map容器中,若沒有,纔將該位置插入map容器中(否則會構成環路)。
算法描述:
初始化map容器,初始化隊列。將下標爲初始位置和值爲0的健值對插入容器map中,將初始位置壓入到隊列中,開始循環,循環繼續的條件爲隊列不爲空。在循環體內,首先從隊列頭取出小易所在的位置,判斷小易所在的位置是不是目標位置,如果是,break跳出循環,如果不是,再判斷小易到當前位置所用的神祕力量次數是否到達上限,如果到達,continue跳出本次循環,進入下一次循環(因爲小易在該位置已經用光了神祕力量,不能再用了,進入下一次循環,看看其他位置的情況)。如果小易這次還能用神祕力量,那就在當前位置使用神祕力量1(4*X+3),再將結果對1,000,000,000,007取餘,得到小易通過神祕力量1移動到的位置,判斷該位置是否在map容器中存在,如果不存在,將當前位置的神祕力量次數加一賦予通過神祕力量1移動到的下一個位置,並將該位置壓入隊列中。如果存在,拋棄使用神祕力量1。同理,如果在當前位置使用神祕力量2(8 * X + 7),再經過取餘,得到了下一個位置,判斷該位置是否在map容器中存在,若不存在,將當前位置的總神祕力量次數加一賦予下一個位置,並將該位置壓入隊列中。如果存在,就拋棄使用神祕力量2,直到循環截止。從循環中出來之後,需要判斷隊列是否爲空,如果爲空,則說明試遍了所有位置都沒有找到,則輸出-1,否則說明循環是從break中退出的,到達目標位置所使用的總神祕力量次數存儲在map容器鍵爲0的位置,輸出即可。

#include <iostream>
#include <map>
#include <queue>

#define MOD 1000000007
#define MAX 100000

using namespace std;

typedef long long ll;

int main(void)
{
    ll x_0;
    cin >> x_0;
    map<ll, int> dist_cnt;
    queue<ll> q;
    q.push(x_0);
    dist_cnt[x_0] = 0;
    ll finalStep;
    while(!q.empty())
    {
        ll curLocal = q.front();
        q.pop();
        if (curLocal == 0)
        {
            finalStep = curLocal;
            break;
        }
        if (dist_cnt[curLocal] > MAX) continue;
        ll nextLocal = (4 * curLocal + 3) % MOD;
        if (dist_cnt.find(nextLocal) == dist_cnt.end())
        {
            dist_cnt[nextLocal] = dist_cnt[curLocal] + 1;
            q.push(nextLocal);
        }
        nextLocal = (8 * curLocal + 7) % MOD;
        if (dist_cnt.find(nextLocal) == dist_cnt.end())
        {
            dist_cnt[nextLocal] = dist_cnt[curLocal] + 1;
            q.push(nextLocal);
        }
    }
    int steps = q.empty() ? -1 : dist_cnt[finalStep];
    cout << steps << endl;
    return 0;
}

若有不對之處,敬請指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章