腾讯2019秋招笔试真题

时间:2022-07-24
本文章向大家介绍腾讯2019秋招笔试真题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1.小Q爬塔

【题目描述】:小Q正在攀爬一座宝塔,这座宝塔很特别,塔共有n层,但是每两层之间的净高却不同,所以造成了小Q爬过每层的时间也不同。如果某一层的高度为x,所以爬过这一层的时间也为x。 小Q还会使用一种魔法,每用一次可以让他向上跳一层或者两层,但是每次跳跃之后小Q都将用完魔法力,必须爬过至少一层才能再次跳跃(你可以认为小Q需要跳两次一层才休息,最后也可以跳到塔外即超过塔高,跳是不花费时间的)。 小Q想用最短时间爬到塔顶,希望你告诉他最短时间是多少。 输入描述: 第一行一个数n(n<10000),表示塔的层数。 接下来的n行每行一个数h(1 <= h <= 100)表示从下往上每层的高度。 输出描述: 一个数,表示最短时间。 输入样例

5
3
5
1
8
4

输出样例

1

【解题思路】 p[i]表示到达第i层的最短时间,并且到达第i层的方式是爬。 t[i]表示到达第i层的最短时间,并且到达第i层的方式是跳。 到达第i层的方式采用爬还是采用跳。

  • 情况1,到达第i层的方式是爬: 那么到达第i层的方式可以是爬也可以是跳,从两者中选择最小的 p[i]=min(p[i-1],t[i-1]+a[i]);
  • 情况2,到达第i层的方式是跳: 那么从第i-1层起跳,也可以从i-2层起跳。到达并且到达第i-1层和i-2层的方式只能是爬(到第i层是跳),所以在两者中选择最小的。 t[i]=min(p[i-1],p[i-1]);

最后在p[n]和t[n]中选最小者做结果。 【代码】

#include<iostream>
#include<algorithm>
using namespace std;
int p[1005], t[1005];
int main()
{
	int n=0;
	cin >> n;
	int m = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> m;
		p[i] = min(p[i - 1], t[i - 1]) + m;
		if (i == 1)
			continue;
		t[i] = min(p[i - 1], p[i - 2]);
	}
	cout << min(p[n], t[n]) << endl;
	system("pause");
	return 0;
}

2.妞妞的问题

【题目描述】妞妞公主新得到一块黑白棋盘。这块棋盘共有n行m列,任意相邻的两个格子都是不同的颜色(黑或白),坐标为(1,1)的格子是白色的。 这一天牛牛来看妞妞公主,妞妞公主正在望着这块棋盘发呆。牛牛看妞妞公主闷闷不乐的样子,便对妞妞公主说“只要你告诉我n和m,我能马上算出黑色方块和白色方块的数量。” “这太简单了”妞妞公主想了一会,“我会在这n行m列中选择一个左下角坐标为(x0,y0)。右上角为(x1,y1)的矩形,把这个矩形里的共(x1-x0+1,y1-y0+1)个方块全部涂白。你还能马上计算出黑色方块和白色方块的数量。” “这太简单了。”牛牛自信的一笑,“你可以在执行涂白操作后再选择一个左下坐标为(x2,y2),右上角坐标为(x3,y3)的矩形,把这个矩阵里面的方块全部涂黑,我依然能马上计算出黑色方块和白色方块的数量。” 妞妞公主张大眼睛,于是抛出了他的T次提问。 聪明的牛牛当然会做了,但是他想把这个问题交给你,请帮助牛牛算出每次提问棋盘的黑白方块数目吧。 输入描述: 第一行一个整数T,表示妞妞一共提问了T次。 接下来3T行, 第(1+3i)行两个整数n,m。表示第i次提问时棋盘的大小。 第(2+3i)行四个整数x0,y0,x1,y1。表示第i次提问时涂白操作选取的两个坐标。 第(3+3i)行四个整数x2,y2,x3,y3。表示第i次提问时涂黑操作选取的两个坐标。 i <= T <= 1000,1 <= x <= n <= 1000000000,1 <= y <= m <= 1000000000,x0<x1,y0<y1,x2<x3,y2<y3。 输出描述: 共T行,每行两个整数分别表示白色方块的数量和黑色方块的数量。 输入样例

3
1	3
1	1	1	3
1	1	1	3
3	3
1	1	2	3
2	1	3	3
3	4
2	1	2	4
1	2	3	3

输出样例

0	3
3	6
4	8

【解题思路】 格子的个数可以快速维护,然后对应维护出来即可。 【代码】

#include<iostream>
using namespace std;
long long x[8], y[8];
int main()
{
	int T;//提问次数
	long long n, m, black, white, a, b, c, d, e;
	scanf("%d", &T);//输入提问次数
	while (T--)
	{
		scanf("%lld%lld", &n, &m);//输入棋盘大小
		black = n*m / 2;//黑色方块数量为总方块数的一半,如果总方块数为偶数,黑白方块数量一样,如果为奇数,黑素方块比白色少一块
		white = n*m - black;//白色方块数量
		for (int i = 0; i <= 3; i++)
			scanf("%lld%lld", &x[i], &y[i]);
		if ((x[0] + y[0]) & 1)//涂白起点决定黑白方块数量差
			d = ((x[1] - x[0] + 1)*(y[1] - y[0] + 1)+1) / 2;//起点和为奇数,说明起点为黑色
		else
		{
			d = ((x[1] - x[0] + 1)*(y[1] - y[0] + 1)) / 2;//起点为偶数,说明起点为白色
		}
		white += d;
		black -= d;
		if ((x[2] + y[2]) & 1)
			d = (x[3] - x[2] + 1)*(y[3] - y[2] + 1) / 2;
		else
		{
			d = ((x[3] - x[2] + 1)*(y[3] - y[2] + 1)+1) / 2;
		}
		white -= d;
		black += d;
		a = max(x[0], x[2]);
		b = max(y[0], y[2]);
		c = min(x[1], x[3]);
		d = min(y[1], y[3]);
		if (c < a || d < b)e = 0ll;
		else//涂白和涂黑区域有重叠
		{
			if ((a + b) & 1)
				e = ((c - a + 1)*(d - b + 1) + 1) / 2;
			else
			{
				e = (c - a + 1)*(d - b + 1) / 2;
			}
		}
		white -= e;
		black += e;
		printf("%lld	%lldn", white, black);
	}
	system("pause");
	return 0;
}

3、小Q的最小值序列

小 Q 得到了一个长度为 n 的序列 A,A 中的数各不相同。对于 A 中的每一个数 Ai,求:min(1≤j<i)|Ai−Aj| 以及令上式取到最小值的 j(记为 P_i)。若最小值点不唯一,则选择使 Aj 较小的那个。 输入描述: 第一行一个整数 n,第二行 n 个数。 输出描述: n-1 行,每行 2 个用空格隔开的整数。分别表示当 i 取 2~n 时,对应的 min(1≤j<i)|Ai−Aj|和 Pi的值 输入样例

3
1 5 3

输出样例

4 1
2 1

【解题思路】 维护一个单调的链表,边读边算边输出,这样每一个数进来时,都能保证链表里的数下标比他小,那么插入后用它两边的数计算答案即可。

【代码】

#include<iostream>
using namespace std;
const int N = 1e5 + 5;
const int inf = 1e9;

struct P
{
	int value;
	int pos;
};
P a[N];
int cmp(P x, P y)
{
	return x.value < y.value;
}
int b[N], b2[N], cnt, head, tail, ans1[N], ans2[N];
struct node
{
	int value;
	int next, pre;
}e[N];

void init(){
	cnt = 2;
	head = 1, tail = 2;
	e[head].next = tail;
	e[head].pre = head;
}
void ins(int pos, int x){//在pos位置后边加一个数X
	e[++cnt].value = x;
	e[cnt].next = e[pos].next;
	e[cnt].pre = pos;
	e[e[pos].next].pre = cnt;
	e[pos].next = cnt;
}

void del(int pos){
	e[e[pos].next].pre = e[pos].pre;
	e[e[pos].pre].next = e[pos].next;
}

int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &a[i].value);
		a[i].pos = i;
	}
	sort(a + 1, a + 1 + n,cmp);
	init();
	for (int i = 1; i <= n; i++)
	{
		ins(e[tail].pre, a[i].value);
		b[a[i].pos] = cnt;
		b2[cnt] = a[i].pos;
	}
	for (int i = n; i >= 2; --i)
	{
		ans1[i] = inf;
		if (e[b[i]].next != tail){
			ans1[i] = min(ans1[i], abs(e[b[i]].value - e[e[b[i]].next].value));
			ans2[i] = b2[e[b[i]].next];
		}
		if (e[b[i]].pre != head){
			if (ans1[i] >= abs(e[b[i]].value - e[e[b[i]].pre].value)){
				ans1[i] = abs(e[b[i]].value - e[e[b[i]].pre].value);
				ans2[i] = b2[e[b[i]].pre];
			}
		}
		del(b[i]);
	}
	for (int i = 2; i <= n; i++)printf("%d %dn", ans1[i], ans2[i]);
	system("pause");
	return 0;
}