2017年腾讯 秋招软件开发笔试编程题回忆版

2017年腾讯秋招软件开发笔试编程题回忆版

(所有题目大致描述如下,并非完整的题目回忆,但意思大致一样)

1、又一个魔法城市,城市里面有n个魔法城堡,序号为0,1,2。。。n-1;魔法城堡之间都有路径相连;魔法城堡两两之间的到达的距离不同,因此所需时间也可能不会相同。如魔法城堡0到魔法城堡2需要耗时4小时;现,小明想从魔法城堡0到魔法城堡1,他想知道需要花费多少时间;为了快速到达,有一魔法扫把,魔法扫把使用次数有限,使用一次,可以将某一段间的时间减半;求小明从魔法城堡0到魔法城堡1花费的最小时间,精确到一位小数。

输入:总共n+1行;

第一行,魔法城堡数n;魔法扫把能够使用的次数k;

第二行到第n行为魔法城堡之间到达需要的时间;

输出:从魔法城堡0到魔法城堡花费的最短时间:t,精确到小数点后一位。

示例:

输入:

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、小明有很多枚硬币,每一枚银币的面值均为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,即为组合情况数)

3、这道编程大体大致是这么描述的,有一台魔法机器,机器上有两个按钮;机器的运算方式是:一次输入两个数字;两个数字根据按下不同的进行同时进行相同的操作。规则如下:红色按钮:按下则两个数,分别同时加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;

}

运行结果如下:(自己调试用的,未按标准输入输出,自行更正)

以上仅供交流,勿喷;本人在规定时间内,未写出这几道题的答案,(┬_┬)??

时间: 2024-12-22 06:24:28

2017年腾讯 秋招软件开发笔试编程题回忆版的相关文章

百度软件开发笔试大题3

对表达式求值.已知运算符只有加减乘除,无负数,结果也不是负数.(类似逆波兰法的算法思路) 思想:对数字只要入栈就可以,需要时拿出来计算.对符号,有几种情况: (1)新符号加入前符号栈中还没有符号,则直接入栈: (2)新符号是加减运算,则将之前符号栈中的符号全部拿出来计算,每次消耗1个符号,2个数字,再将得到的结果压入数字栈: (3)新符号是乘除,之前的符号也是乘除,则只需要消耗一个符号就行: (4)新符号乘除,原来符号加减,则符号压栈即可. Eg. 1+4*5+2*3,定义两个栈分别存数字和符号

美团点评2017秋招笔试编程题

美团点评2017秋招笔试编程题 1, 大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步.求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法. 题解: 写出前面的几个, 1 -> 1;   2 -> 2 ;  3 -> 4;   4 -> 8; 5 -> 16; 6 -> 32; 可以得到是 二的 n-1 次幂. #include <cstdio> int

2019秋招软件工程师面经

秋招已经尘埃落定,十月下旬把三方寄出去之后又出去玩了一周,现在开始复盘整个秋招. 首先,这两年互联网行业真的行业不太好,很多公司的岗位趋于饱和,门槛也高了不少(我自己在秋招过程中的感觉,也可能是我自己菜,菜是原罪),找工作要很早开始准备才行. 个人的一些信息:大四应届生,软件工程专业,成绩还行. 关于读研与否的选择:这个问题在面试过程中被问过好几次,我是寒假下定的决心,之后几乎就没再动摇过.我找到了一张当时的自己的微博截图: 总而言之还是自己太菜了叭,感觉自己搞不来科研,而且本科毕业搞搞开发..

BZOJ_1221_ [HNOI2001]_软件开发(网络流24题,最小费用流)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1221 n天,每天需要r个毛巾,用完以后可以洗,要么花fa洗a天,要么花fb洗b天,毛巾不够了可以话f买一个,问最少需要多少钱. 分析 把每天拆成两个点:x[i]表示第i天的脏毛巾,y[i]表示第i天要用的毛巾. 1.s向x[i]连弧,容量为r[i],花费为0,表示每天会用脏r[i]条毛巾. 2.x[i]向x[i+1]连弧(注意边界),容量为INF,花费为0,表示把第i天的脏毛巾搁置到第i+1

H3C软件开发笔试面试总结

注:我目前是陕西师范大学计算机科学学院本科生,在西安参加笔试以及面试 先是笔试,我选择的是JAVA方向,笔试选择题目主要是一些基础性的题目,然后简答题问了final.finally.finallize的区别,以及修饰符有几种各有什么区别,还是比较基础的,编程题第一道是求[200,300]内的质数,第二道就是快排. 总的来说笔试相对比较重视基础,客观来说难度一般,但是由于我转JAVA的时间也不是很长,选择中一些考察语言特性的题目还不会,这也是这次笔试中暴露出来的问题. 然后是面试,面试在笔试一周后

秋招--线上笔试记录

这系列帖子用来记录的我凉凉的线上笔试,第一次笔试让我更加深刻的认识到了自己的不足,以及还有许多知识点没有看,算法这一块我看来还没入门,只能说秋招道路任重而道远.希望去北京的这条路自己可以能走得再快一点. 下面来记录一下,在这次笔试的我的一些问题 单选 1.最短路径:用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. 2.通过构建有序序列,对于未排序数据,在已排序序

2017腾讯秋招笔试题之编码

Description: 假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa, aaaa, aaab, aaac, - -, b, ba, baa, baaa, baab, baac - -, yyyw, yyyx, yyyy 其中a的Index为0,aa的Index为1,aaa的Index为2,以此类推.    编写一个函数,输入是任意一个编码,输出这个编码对应的Index Input: 输入一个待编码的字

2017年9月秋招记录--持续更新

一.腾讯校招提前批(一面跪) 二.网易内推(笔试跪) 三.今日头条(免笔试,二面跪) 四.蘑菇街(免笔试,一面跪) 五.好未来(免笔试,一面跪) 六.360(笔试跪) 七.大疆(笔试跪) 八.美团(笔试等通知) 九.百度校招提前批(二面通过,等三面) 十.高德地图(等一面) 十一.拼多多(三次笔试跪) 十二.亚马逊中国(待笔试) 十三.51信用卡 十四.中国银联 十五.招商银行 十六.深信服 十七.趋势科技 十八.去哪网

美团点评2017秋招笔试编程题——大富翁游戏

大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步.求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法. 输入描述: 输入包括一个整数n,(1 ≤ n ≤ 6) 输出描述: 输出一个整数,表示投骰子的方法 思路:递归的思路.n=1时,有1种方法:n=2时,有2种方法:n=3时,有4种方法,在当前n步时应该有前n-1步的方法数加上当前直接投n的方法.即f(n)=f(n-1)+f(n-2)+...+f(