9月15日腾讯 C++游戏客户端 笔试分享

前排先说一下,根据个人经验,笔试基本上只要能过线就行,对后续流程影响真的不大。

我已经不知道有多少家公司,笔试题全A,然后简历被刷,或是一面后被刷了。

我腾讯的流程其实已经结束了。

所以诸位不用对笔试成绩过分看重。

奇怪了,我发布时代码选的是C++,发出来变成plain text了

腾子这次笔试题难度还是不太大的,比美团难一些,不过肯定比米哈游网易雷火这种笔试简单的多。

1、对k个链表进行排序。

思路:初看以为是k个升序链表(样例是升序),仔细一看题目描述链表是乱序的,所以直接摧毁原始链表,提取所有数值并排序,最后用排序好的数值重新建一个链表即可,没必要在链表上进行操作。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 返回一个指向链表头部的指针。
     * @param a ListNode类vector 指向这些数链的开头
     * @return ListNode类
     */
    ListNode* solve(vector<ListNode*>& a) {
        vector<int> nums;

        for (auto& head : a)
        {
            while (head != nullptr)
            {
                nums.emplace_back(head->val);
                auto node_next = head->next;
                delete(head);
                head = node_next;
            }
        }

        sort(nums.begin(), nums.end(), [](int a, int b) {return a < b; });
        ListNode* head = new ListNode(nums[0]);
        ListNode* tmp_node = head;
        for (int i = 1; i < nums.size(); i++)
        {
            tmp_node->next = new ListNode(nums[i]);
            tmp_node = tmp_node->next;
        }

        return head;
    }
};

2、对一个正整数数组中的数字执行k次操作,求k次操作后数组和的最小值。对数字的操作如下:

如果x是偶数,则操作后x = 2*x + 1

如果x是奇数,则操作后x = 2*x

思路:简单贪心即可,每次操作最小的那个数字即可。用优先队列更好,但是忘了如何规定优先队列升序还是降序,所以用了map

#include<iostream>
#include<map>
using namespace std;

int main()
{
	int n, k;
	cin >> n >> k;

	long long sum = 0;
	map<long long, int> nums;
	for (int i = 0; i < n; i++)
	{
		long long num;
		cin >> num;
		nums[num]++;
		sum += num;
	}

	for (int i = 0; i < k; i++)
	{
		auto it = nums.begin();
		long long num = it->first;
		sum -= num;

		if (num % 2 == 0)
			num = num * 2 + 1;
		else
			num = num * 2;

		it->second--;
		if (it->second == 0)nums.erase(it);
		nums[num]++;
		sum += num;
	}

	cout << sum << endl;
	return 0;
}

3、有n辆赛车,以及所有赛车的当前位置p,速度v,假设赛车均做匀速直线运动。问你t时刻后,有多少赛车的名次发生了改变?

思路:初始输入是有序的,只用对t时刻后的位置重新排序重新计算名次即可。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

struct car
{
	int pos = 0;
	int rank_now = 0;
	int rank_new = 0;
};

int main()
{
	int n, t;
	cin >> n >> t;

	vector<car> cars(n);
	for (int i = 0; i < n; i++)
	{
		cin >> cars[n - 1 - i].pos;
	}

	cars[0].rank_now = 1;
	for (int i = 1; i < n; i++)
	{
		if (cars[i].pos == cars[i - 1].pos)
			cars[i].rank_now = cars[i - 1].rank_now;
		else
			cars[i].rank_now = i + 1;
	}

	for (int i = 0; i < n; i++)
	{
		int v;
		cin >> v;
		cars[n - 1 - i].pos += v * t;
	}

	sort(cars.begin(), cars.end(), [](car a, car b) {return a.pos > b.pos; });

	int count = 0;
	cars[0].rank_new = 1;
	if (cars[0].rank_now > cars[0].rank_new)count++;
	for (int i = 1; i < n; i++)
	{
		if (cars[i].pos == cars[i - 1].pos)
			cars[i].rank_new = cars[i - 1].rank_new;
		else
			cars[i].rank_new = i + 1;

		if (cars[i].rank_now > cars[i].rank_new)
			count++;
	}

	cout << count << endl;
	return 0;
}

4、对于一个字符串,将其首字符放在末尾,这个操作称为旋转字符串("abcdef" -> "bcdefa") 。对于两个字符串,如果其中一个字符串可以通过一次或多次旋转变成另一个字符串,则这两个字符串“互旋”

给你T组数据,问你每组数据中是否存在两个字符串“互旋”?

思路:观察数据量,字符串数量很多,字符串长度不长,如果两两比较肯定超时,应当用哈希表匹配。

#include<iostream>
#include<string>
#include<unordered_set>
using namespace std;

int main()
{
	int T;
	cin >> T;

	for (int i = 0; i < T; i++)
	{
		int n;
		cin >> n;

		bool isFind = false;
		unordered_set<string> strs;
		for (int j = 0; j < n; j++)
		{
			string str;
			cin >> str;

			if (isFind)continue;

			for (int k = 0; k < str.length(); k++)
			{
				std::rotate(str.begin(), str.begin() + str.length() - 1, str.end());
				if (strs.find(str) != strs.end())
				{
					isFind = true;
					break;
				}
			}

			if (!isFind)
				strs.insert(str);
		}

		if (isFind)
			cout << "YES" << endl;
		else
			cout << "NO" << endl;
	}

	return 0;
}

5、有n个数字,数字可能为0可能为1,告诉你每个数字的坐标值。你可以将k个1变为0。

你每次操作可以让一个0的位置+1或是-1,。

问你最少需要几次操作使得所有0之间没有1。(如果0和1重合,视为中间有1)

思路:对于所有1

计算将1左侧所有0移动到1右侧的操作数(表示将所有0移动到这个1右侧需要的代价lcost)

计算将1右侧所有0移动到1左侧的操作数(表示将所有0移动到这个1左侧需要的代价rcost)

在所有数字左侧添加一个1,其左代价lcost = 0;在所有数字右侧添加一个1,其右代价rcost = 0;

那么,对于两个1,左侧的1的lcost和右侧的1的rcost加起来,即是将所有0移动到这两个1之间所需要的操作数。

遍历所有1,求lcost[i] 与rcost[i + k + 1](因为可以将中间k个1变为0,所以右侧选i + k + 1)的最小值即可

#include<iostream>
#include<vector>
using namespace std;

int main()
{
	int n, k;
	cin >> n >> k;

	vector<long long> pos(n);
	vector<int> color(n);
	vector<int> blue_idx;
	for (int i = 0; i < n; i++)
	{
		cin >> pos[i];
	}
	for (int i = 0; i < n; i++)
	{
		cin >> color[i];
		if (color[i] == 1)
		{
			blue_idx.emplace_back(i);
		}
	}

	int num_blue = blue_idx.size();
	vector<long long> lcost(num_blue + 2, 0);
	vector<long long> rcost(num_blue + 2, 0);
	
	int lnum = 0;
	long long lpos = 0;
	long long lidx = -1;
	for (int i = 0; i < num_blue; i++)
	{
		long long pos_now = pos[blue_idx[i]];
		lcost[i + 1] = lcost[i] + (pos_now - lpos) * lnum;
		for (int p = lidx + 1; p < blue_idx[i]; p++)
		{
			lcost[i + 1] += pos_now - pos[p] + 1;
			lnum++;
		}

		lpos = pos_now;
		lidx = blue_idx[i];
	}

	int rnum = 0;
	long long rpos = pos[n - 1];
	long long ridx = n;
	for (int i = num_blue; i > 0; i--)
	{
		long long pos_now = pos[blue_idx[i - 1]];
		rcost[i] = rcost[i + 1] + (rpos - pos_now) * rnum;
		for (int p = ridx - 1; p > blue_idx[i - 1]; p--)
		{
			rcost[i] += pos[p] - pos_now + 1;
			rnum++;
		}

		rpos = pos_now;
		ridx = blue_idx[i - 1];
	}

	long long cost_min = lcost[num_blue];
	for (int i = 0, j = k + 1; j <= num_blue + 1; i++, j++)
	{
		long long cost_now = lcost[i] + rcost[j];
		if (cost_now < cost_min)
			cost_min = cost_now;
		//if (cost_now == 0)
		//{
		//	int p = j - 1;
		//	while (p > i && lcost[i] + rcost[p] == 0)p--;
		//	if (cost_min > p - i)
		//		cost_min = p - i;
		//}
		//else
		//{
		//	int p = j - 1;
		//	while (p > i && lcost[i] + rcost[p] == cost_now)p--;
		//	if (cost_min > cost_now + p - i)
		//		cost_min = cost_now + p - i;
		//}
	}
	cout << cost_min << endl;
	return 0;
}

全部评论
想问大佬第五题一般属于啥算法类型,刷少了这部分想不到
1 回复 分享
发布于 2023-09-16 18:11 上海
前排捕捉文佬,太强了😭
1 回复 分享
发布于 2023-09-15 23:01 浙江
除了代码之外有考图形学,操作系统之类的题吗大佬
点赞 回复 分享
发布于 2024-04-23 10:36 英国
关注了 大佬有没有兴趣有偿一对一辅导一下代码能力呀
点赞 回复 分享
发布于 2023-12-19 11:20 浙江
看起来解题不错呀,阿里盒马客户端P5岗位可以考虑下,二维码直达:
点赞 回复 分享
发布于 2023-09-22 10:40 浙江
大佬题解好牛……请问大佬笔试一般多少分能过线呀?
点赞 回复 分享
发布于 2023-09-16 18:50 广东
我ak了,但之前已经一面挂了
点赞 回复 分享
发布于 2023-09-15 23:45 云南
第五题做了四十分钟,放弃了
点赞 回复 分享
发布于 2023-09-15 23:29 河南
这题解看的津津有味😆
点赞 回复 分享
发布于 2023-09-15 23:24 上海

相关推荐

从年初开始就有陆陆续续高强度刷牛客,牛友的面经确实帮到了我很多,我目前的求职方向是游戏客户端,暑假也很幸运找到了一家中厂收留,但说实话感觉我无论是在八股,项目,实习(仅目前这段实习)上都非常薄弱,唯一能拿得出手的只有算法(但也只能算略略好,有一丢丢oi和xcpc经历,但感觉自己还是完全只能写模拟题思维题之类的,上复杂一点的数据结构没有板子就不太写的来)这几个月干活真的学到了很多,但是因为我的经验很匮乏,学到了很多,干了很多,我也没办法具体地评估我现在到底水平怎么样,也不知道这段实习的产出算多还是不多,算有效还是算无效今天刷到一条xhs,那位同学说觉得自己代码能力很弱,日常做需求完全离不开ai。我不禁很疑惑,什么样的代码能力算不弱呢,我现在开发是写csharp,但是我其实对csharp完全就是仅凭借c++的基础上手,语法呀特性呀有些虽然看了八股但是也不算很熟练,要用的时候或者有看不懂的代码的时候就ai一下这几个月下来基本上常用的部分已经都熟悉了,不过还是有看项目代码的时候会遇见不懂的部分,基本上ai都可以为我解答,我大概了解了是做啥用的,也能上手用了每天的工作大概就是,mt说让我这周做xxx工作,我就去看相关的接口,梳理对应的逻辑,想一下逻辑要扩展在哪里,加个组件还是咋滴处理大部分时候只要把我要做的事情的每一步大概想清楚,这个协议少一个字段就加一个,这个地方少一个方法就加一个,这个地方少一个回调就加一个,我习惯把写的过程抽象成:我现在已经有哪些输入了,还差哪些输入没有,想一下怎么获取对应的数据;我现在有这些输入了,我要输出什么,要输出这些,那我就这样那样写逻辑就行中间有不熟悉的api就问ai,能看懂马上上手的,我就自己写,不能很快上手的就让ai写,把它写的看懂了我再一句一句粘到项目里适应修改(其实逻辑都还好,大部分时间感觉都是在解决开发过程中遇到的意料之外的问题,或者解决流程上的问题)大致的开发节奏就是这样了,这样的开发算是怎样的水平呢?我感觉自己完全没有办法评判这些,有时候也不知道自己做的工作算不算有效产出,到底怎样的工作内容才算是写在简历上很有含金量的呢?对框架做扩展,性能优化,给场景添加四叉树,扩展行为树系统,扩展timeline,这些算吗?我浅薄的认知里觉得好像这些可以属于比较高级的工作内容
投递牛客等公司
点赞 评论 收藏
分享
08-12 23:18
中山大学 C++
笔试2题只a了一题,竟然过了。一面面试官感觉挺年轻的,很好人。面了一个半小时,总体上是提出问题后不断深挖1、给了一个结构体,问大小,各成员的首地址2、怎么修改可以减少总大小3、通过什么方法可以修改对齐的规则(这个不知道)4、那我现在想要压缩这个结构体,只使用15字节(成员总大小)的空间要怎么放针对这个问题让我写一下伪代码,我的思路用一个int8数组存,把大于一个字节的成员转成int8数组格式,然后分别放进数组里。然后根据我的代码连续问了好几个问题,最后一个是:uint8_t&nbsp;array[15],把一个double&nbsp;num存进去,让其放在array下标1-8的位置。这个问题没答上来,面试官就作出了解答5、struct&nbsp;alignas,加上这个原结构体的size是多少6、介绍一下虚拟内存7、从虚拟地址到物理地址的具体寻址过程,比如cpu干了什么8、内存分页是为了解决什么问题9、介绍一下三次握手10、第三次握手发的ACK是为了回应什么?(第二次握手中的SYN)11、介绍一下四次挥手12、为什么第四次挥手要等待这么长的时间,这样设计是为了什么13、连接完成后,假如client突然掉了,且此时网络中没有任何数据收发,那么server可以通过协议栈的方法得知client挂了吗?这里不是很熟,我说感觉server应该不知道。然后问那么通过怎么样的方法可以让server知道,这时突然想到keep-alive就提了一下,面试官说他的查询间隔是多少,会不会有点长(这里具体的间隔是多少主播不懂)让我设计一个方法的话会怎么设计。我就联想到一秒有多少帧,可以就按这个频率发送检测,如果send()和recv()正常就代表连接正常14、如果server开启listen()状态后突然挂了,然后直接重启服务器代码的话会出现什么错误?怎么避免?15、介绍一下IO多路复用的select、poll、epoll。把之前看的东西都说了一下,然后也继续问多了几个问题,只记得一个这三个哪个能用在windows上16、问python的问题,问知道GIL吗?(我说不知道,对python的细节不是很熟,只是会用python做科研项目,面试官就没继续拷打了)17、时间到50min的时候,说出个代码题,说说思路就好。让实现Timer和TimerManager。后面查了一下才知道这个是比较高频的考点,但是完全没接触过(一开始还以为是实现一个计时的秒表),不过面试官会全程引导,我一开始说完思路后面试官会抛出一些问题指引我要使用什么数据结构、联想一下前面说的多路复用等等18、这里说了20多分钟,最后让我介绍一下之前实习的项目,讲了10min左右19、反问总体来说问的挺多的,有些问题我就说不熟悉然后猜了一下,面试官会问为什么这样猜,或者加以引导
查看21道真题和解析
点赞 评论 收藏
分享
评论
17
44
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务