2017年騰訊 秋招軟件開發筆試編程題回憶版

2017年騰訊秋招軟件開發筆試編程題回憶版node

(全部題目大體描述以下,並不是完整的題目回憶,但意思大體同樣)ios

一、又一個魔法城市,城市裏面有n個魔法城堡,序號爲0,1,2。。。n-1;魔法城堡之間都有路徑相連;魔法城堡兩兩之間的到達的距離不一樣,所以所需時間也可能不會相同。如魔法城堡0到魔法城堡2須要耗時4小時;現,小明想從魔法城堡0到魔法城堡1,他想知道須要花費多少時間;爲了快速到達,有一魔法掃把,魔法掃把使用次數有限,使用一次,能夠將某一段間的時間減半;求小明從魔法城堡0到魔法城堡1花費的最小時間,精確到一位小數。編程

輸入:總共n+1行;spa

第一行,魔法城堡數n;魔法掃把可以使用的次數k;調試

第二行到第n行爲魔法城堡之間到達須要的時間;blog

輸出:從魔法城堡0到魔法城堡花費的最短期:t,精確到小數點後一位。排序

示例:ci

輸入:開發

3 2字符串

094

904

440

(注:騰訊這裏輸入的094,904,440,是以字符串的形式輸入的)

輸出:

4.0

我的大體思路:

利用Dijkstra最短路徑求法;記錄到魔法城堡1的最短路徑上每個前驅節點和對應的距離;而後對每段的距離進行降序排序;以後把魔法掃把使用在所耗時最多的段中。如0到1的最短路徑爲0到2,消耗爲4;2到1消耗爲3;魔法掃把能使用1次;那麼把這一次機會使用在0到2這一段路徑上;那麼最後最短期即爲:2+3=5.0;

代碼實現爲:

#include <iostream>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <cstring>

#include <math.h>

#include <algorithm>

 

using namespace std;

 

#define MIN              99999

 

vector<int> dijkstra_shortpath(vector<vector<int>> arcs, int ednode)

{

       int size = arcs.size();

 

       vector<int> dist(size);      //保存當前最短路徑

       vector<int> path(size);     //保存前驅節點

       vector<int> S(size);          //保存已經找到最短路徑的節點

 

       //初始化

       for (size_t i = 0; i < size; i++)

       {

              dist[i] = arcs[0][i];

              S[i] = 0;

              path[i] = 0;  

       }

       S[0] = 1, path[0] = -1;

 

       //進行循環更新每次遍歷每一個節點的最短路徑長度

       for (int i = 1; i < size; i++)

       {

              int nmin = MIN, mi = 1;

              for (int j = 1; j < size; j++)

              {

                     if (!S[j] && dist[j] < nmin)

                     {

                            mi = j;

                            nmin = dist[j];

                     }

              }

              cout << "min index=" << mi << "; paht="<<nmin << endl;

              S[mi] = 1;

 

              //更新每一個節點的最短路徑長度

              for (int j = 1; j < size; j++)

              {

                     if (!S[j] && dist[mi] + arcs[mi][j] < dist[j])

                     {

                            dist[j] = dist[mi] + arcs[mi][j];

                            path[j] = mi; //保存節點j最短路徑的前驅mi

                     }

              }

       }

       //輸出每一個節點的

       for (int i = 0; i < size; i++)

       {

              cout << "[pre=" << path[i] << ",len=" << dist[i] << "]; ";

       }

       cout << endl;

       vector<int> res;

       while (path[ednode] != -1)

       {

              res.push_back(arcs[path[ednode]][ednode]);

              cout << "[pre=" << path[ednode] << ";len=" << arcs[path[ednode]][ednode] << "];";

              ednode = path[ednode];

       }

       cout << endl;

       return res;

}

int main(int argc,char **argv)

{

       int n = 0, k = 0;

       vector<int> res;

       while (cin >> n>>k)

       {

              vector<vector<int>> nodes;

              string path;

              for (int i = 0; i < n; i++)

              {

                     cin >> path;

                     vector<int> node(n);

                     for (int i = 0; i < n; i++)

                            node[i] = path.at(i) - '0';

 

                     nodes.push_back(node);

              }

              res = dijkstra_shortpath(nodes, 1);

              sort(res.begin(), res.end());//默認是升序遍歷

 

              int sum = 0;

              for (int i = res.size() - 1; i >= 0; i--)

              {

                     if (k > 0)

                     {

                            sum += res[i] / 2;

                            k -= 1;

                     }

                     else sum += res[i];

              }

              cout << "min cost time=" << sum << endl;

       }

       return 0;

}

運行效果下圖所示:

 

二、小明有不少枚硬幣,每一枚銀幣的面值均爲2的k次方,而且該類硬幣的數量均爲2枚;也便是他的硬幣的序列是:1,1,2,2,4,4,8,8。。。;如今他去超市買東西,須要支付總額爲n;問他有多少種支付方式,也便是有多少種硬幣的組合的和爲n;(騰訊給的示例,想不起來了)

我的大體思路是:利用圖的深度優先遍從來作這道到,該過程得出的結果確定有一部分結果是重複的,則須要去重;暫時未想到其餘很好的辦法。

代碼實現以下:

#include <iostream>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <cstring>

#include <math.h>

#include <algorithm>

 

using namespace std;

 

vector<int> res;

 

int get_cnt(int depth, int cur_sum, int target, set<vector<int>>& sres)

{

       if (cur_sum == target)

       {

              vector<int> tmp;

              for (int i = 0; i < res.size(); i++)

              {

                     tmp.push_back(res[i]);

                     cout << res[i] << ", ";

              }

              cout << endl;

              sres.insert(tmp);

              return 1;

       }

       if (cur_sum > target ) return 0;

 

       for (int i = depth; i < target * 2; i++)

       {

              cur_sum += pow(2, (i / 2));

 

              res.push_back(pow(2, (i / 2)));

 

              //cout << "push tms = " << i << "; sum = " << cur_sum << endl;

 

              get_cnt(i + 1, cur_sum, target, sres) ? 1 : 0;

 

              res.pop_back();

 

              cur_sum -= pow(2, (i / 2));

              //cout << "popo tms = " << i << "; sum = " << cur_sum << endl;

       }

       return 0;

}

 

int main(int argc, char **argv)

{

       int target = 0;

 

       while (cin >> target)

       {

              set<vector<int>> sres;

              get_cnt(0, 0, target, sres);

 

              cout <<"set size = " << sres.size() << endl;

       }

       return 0;

}

運行效果下圖所示:(注:set size,即爲組合狀況數)

 

 

三、這道編程大致大體是這麼描述的,有一臺魔法機器,機器上有兩個按鈕;機器的運算方式是:一次輸入兩個數字;兩個數字根據按下不一樣的進行同時進行相同的操做。規則以下:紅色按鈕:按下則兩個數,分別同時加1;藍色按鈕按下:兩個數分別同時*2。如今小明想知道,他有兩個數,和與之對應的目標數,分別記爲a,b,A,B;通過多少次按鈕操做可以把a變成A;的同時b變成B;輸出按鈕操做的最少次數;若是不能則輸出-1。

示例輸入:

100 1000 202 2002

輸出:

2

代碼大體以下,正確性很難講:

#include <iostream>

#include <vector>

#include <string>

#include <map>

#include <set>

#include <cstring>

#include <math.h>

#include <algorithm>

using namespace std;

int get_opera_cnt(int a, int A)

{

       int cnt = 0;

 

       if (A % 2 == 1)   //把它變成偶數

       {

              A -= 1;  //表示紅色按鈕按一次

              cnt += 1;

       }

       if (A / 2 >= a)

       {

              while (A % 2 == 0 && A / 2 >= a)

              {

                     cnt += 1;

                     A = A / 2;    //表示藍色按鈕按一次

              }

              cnt += (A - a);//表示紅色按鈕按(A-a)次

       }

       else

              cnt += (A - a);//表示紅色按鈕按(A-a)次

 

       return cnt;

}

 

int main(int argc, char **argv)

{

       int a, b, A, B;

       while (cin >> a >> b >> A >> B)

       {

 

              int acnt = get_opera_cnt(a, A);

              int bcnt = get_opera_cnt(b, B);

 

              cout << "acnt=" << acnt << "; bcnt=" << bcnt << "; opera tms=";

              if (acnt == bcnt)cout << acnt << endl;

              else cout << -1 << endl;

       }

       return 0;

}

運行結果以下:(本身調試用的,未按標準輸入輸出,自行更正)

 

 

以上僅供交流,勿噴;本人在規定時間內,未寫出這幾道題的答案,(┬_┬)😞

相關文章
相關標籤/搜索