hw笔试题目解析(5.24)

华为5.24笔试题目全解析

1、华为笔试,连续空闲内存合并管理;

其实就是找最长的连续子串,并返回最小的下标值;

输入

输入:1,3,2,5 表示释放四块内存,ID分别为1.3.2.5,每块内存的大小为1个单位[预制条件]

函数执行前,所有内存均已被申请完毕,无空闲,不需考虑内存重复释放[取值范围]

内存ID编号:0<ID<2^31-1,单次释放的内存个数<10000

输出

输出:1,3 经过回收处理后,当前可用的最大连续内存大小3,以及此内存的起始编号1. 说明:1,3,2,5四块内存,前面三块1,3,2为连续内存,合并后的连续内存数为3个单位起始编号为1,因此返回1,3

代码分析:


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

int main() {
	vector<int> nums;
	string input;
	getline(cin, input);
//也可以这样去解析字符串
//	for (char a : input)
//	{
//		if (a == ',')
//			continue;
//		else
//		{
//			int num = a - '0';
//			nums.push_back(num);
//		}
//
//	}
	size_t pos = 0;
	string token;

	while ((pos = input.find(",")) != string::npos) {  //找不到返回npos
		token = input.substr(0, pos);
		nums.push_back(stoi(token));
		input.erase(0, pos + 1);  //删除从0开始的pos+1个字符
	}
	nums.push_back(stoi(input));

	sort(nums.begin(), nums.end()); //升序排列

	int st = -1, mxlen = -1;
	int n = nums.size();
	int index = 0;
	while (index < n) {
		int i = index;
		for (int j = index + 1; j < n; j++) {
			if (nums[j] - nums[i] != 1)
				break;
			i++;
		}
		//循环操作完之后更新最大值
		if (mxlen < i - index + 1) {
			mxlen = i - index + 1;
			st = index;
		}
		index = i + 1;  //下一波开始
	}

	cout << nums[st] << ", " << mxlen << endl;

	return 0;
}

2、华为笔试,海量日志抑制

海量日志”定义: 10ms内(<10ms)打印2条相同日志 (包含第2条均需要被抑制),即:仅保留第一条或100ms内(<100ms)打印10条相似日志(去除数字后完全相同的两条日志认为是“相似”,包含第10条均需要被抑制),即:仅保留前9条。日志抑制的理解:被抑制的日志,不记录到日志文件中

输入

本用例的日志条数(最大不超过1000条) 时间截:日志打印内容

约束

1、时间戳单位是ms,用32位无符号+进制整数表示
2、用例保证后一条日志时间戳不小于前一条;
3、一条日志打打印只占一行,一条日志内容不超过1024 Bytes;
4、用例保证1s内(<1s),最多100条日志
5、数字均为正整数。

输出

时间戳:日志打印内容 输出需要除去被抑制的日志

代码分析:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <regex>
#include <string>
#include<sstream>
using namespace std;

int main() {
	int n;
	cin >> n;
	cin.ignore(); //清除以回车结束的输入缓冲区的内容,

	vector<pair<int, string>> records;
	unordered_map<string, vector<pair<int, int>>> same;
	unordered_map<string, vector<pair<int, int>>> like;
	vector<bool> vst(n, true);

	for (int i = 0; i < n; i++) {  //i表示行数


		string line;
		getline(cin, line);  //getline会丢弃换行符
		istringstream iss(line); //字符串的输入流
		// 有参构造,输入流 ,默认构造表示输入流的结束位置
		//输入流迭代器,划分成一个个单词 
		//istream_iterator<string>默认以空白字符(包括空格、制表符、换行符等)作为分隔符来提取字符串
		vector<string> lines(istream_iterator<string>{iss}, istream_iterator<string>()); //范围构造函数
		int time = stoi(lines[0]); //哪怕后面有字母 也只会转换数字
		//text是后面的字符串
		string text = "";
		for (int j = 1; j < lines.size(); j++) {
			text += lines[j];
			if (j != lines.size() - 1)
				text += " ";
		}
		same[text].push_back(make_pair(time, i));
		//\\d表示匹配任意数字字符,+表示匹配前面的元素一次或多次。
		//regex_replace(text, regex("\\d+"), ""):这是一个使用正则表达式进行替换的函数调用
		//将所有数字替换为空字符串,删掉数字
		string likeText = regex_replace(text, regex("\\d+"), ""); //不喊时间和数字
		like[likeText].push_back(make_pair(time, i));
		records.push_back(make_pair(time, text)); //用来记录 所有的信息
	}

	//判断相同的日志
	for (auto& d : same) {
		vector<pair<int, int>>& record = d.second;
		for (int i = 0; i < record.size(); i++) {
			int time = record[i].first;
			int index = record[i].second;
			if (i + 1 < record.size() && record[i + 1].first - time < 10)  //满足相同日志条件
				vst[index + 1] = false;
		}
	}
	//判断相似的日志
	for (auto& d : like) {
		vector<pair<int, int>>& record = d.second;
		for (int i = 0; i + 9 < record.size(); i++) {
			int time = record[i].first;
			int index = record[i].second;
			if (record[i + 9].first - time < 100)
				vst[index + 9] = false;
		}
	}

	for (int i = 0; i < records.size(); i++) {
		if (vst[i])
			cout << records[i].first << " : " << records[i].second << endl;
	}

	return 0;
}

3、华为笔试,网络升级改造

输入的网络是一个满二叉树结构,每个网络节点上标注一个数值,表示该节点的每年维护成本费用。给定每个输入网络,按照要求撤掉某些节点后,求出能够节省的最大的维护成本(这个题就类似二叉树的打家劫舍问题)

输入

第一行:一个正整数N,表示后面有N个数值。1<=N<= 10000 第二行:N个非负整数,表示网络节点每年的维护成本,按照满二又树的”广度优先遍历序号”给出。0表示不存在该关联节点,0只会存在于叶子节点上。每个数字的取值范围为[0.1000]

示例:

输入

第一行输入:7,表示后面有7个数字。

第二行输入:5 3 5 0 6 0 1,表示”表示网络节点每年的维护成本,按照满二叉树的“广度优先遍历序号”给出。0表示不存在该关联节点”

输出

能够节省的最大的维护成本。 12

按照二叉树的打家劫舍去做:

#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>
#include<unordered_map>
using namespace std;
struct TreeNode
{
	int val;
	TreeNode *left;
	TreeNode * right;
	TreeNode():val(0),left(nullptr),right(nullptr){}
	TreeNode(int x) :val(x), left(nullptr), right(nullptr) {}
	TreeNode(int x, TreeNode * left, TreeNode* right) :val(x), left(left), right(right) {}
};

unordered_map<TreeNode*, int>memo;
int rob(TreeNode* root)
{
	if (root == nullptr)
		return 0;
	if (memo.count(root))
		return memo[root];
	int do_it = root->val
		+ (root->left == nullptr ? 0 : rob(root->left->left) + rob(root->left->right))
			+ (root->right == nullptr ? 0 : rob(root->right->left) + rob(root->right->right));
	int not_do = rob(root->left) + rob(root->right);
	int res = max(do_it, not_do);
	memo[root] = res;
	return res;
}
TreeNode* buildtree(vector<int>& input)  //根据层序遍历去构造二叉树
{
	if (input.empty()) return nullptr;

	TreeNode* root = new TreeNode(input[0]);
	queue<TreeNode*>q;
	q.push(root);
	for (int i = 1; i < input.size();)
	{
		TreeNode* next_head = q.front();
		q.pop();
		int left = input[i++];
		if (left != 0)
		{
			next_head->left = new TreeNode(left);
			q.push(next_head->left);
		}
		else
		{
			next_head->left = nullptr;
		}
		int right = input[i++];
		if (right != 0)
		{
			next_head->right = new TreeNode(right);
			q.push(next_head->right);
		}
		else
		{
			next_head->right = nullptr;
		}
	}
	return root;
}
int main()
{
	vector<int>input;
	int num;
	cin >> num;
	for(int i = 0; i < num; i++)
	{
		int a;
		cin >> a;
		input.push_back(a);
	}
	if (num == 1)
	{
		cout << input[0] << endl;
		return 0;
	}
	TreeNode * root = buildtree(input);


	int res = rob(root);
	cout << res << endl;
	system("pause");
	return 0;

}

不构建二叉树,直接dfs:

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

int n;
vector<int> nums;
unordered_map<int, int> dp;

//node对应索引


int dfs(int node) {
    if (node >= n) return 0;//>= 因为会*2
    if (dp.count(node)) return dp[node];//类似备忘录
  
    // Select
    //在层序遍历的情况下,node*2+1对应这个节点的左子树,node*2+2对应右子树,再套一层*2+1就是左子树的下一个左子树
    // 选择这个节点,这个节点的左子树和右子树不选择
    int cur = dfs((node * 2 + 1) * 2 + 1) + dfs((node * 2 + 1) * 2 + 2) + dfs((node * 2 + 2) * 2 + 1) + dfs((node * 2 + 2) * 2 + 2) + nums[node];
  
    // Don't select
    cur = max(cur, dfs(node * 2 + 1) + dfs(node * 2 + 2));
    dp[node] = cur;
    return cur;
}

int main() {
    cin >> n;
    nums.resize(n);
    for (int i = 0; i < n; i++) {
        cin >> nums[i];
    }

    cout << dfs(0) << endl;

    return 0;
}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: emwin是一种运行于嵌入式系统上的图形界面开发工具,能够提供丰富的图形显示功能。移植emwin5.24版本指的是将这个工具移植到标嵌入式系统上,使其能够在该系统上正常运行。 移植emwin5.24版本的过程主要包括以下几个步骤: 首先,需要了解标嵌入式系统的硬件平台和操作系统。emwin5.24支持多种硬件平台和操作系统,因此需要根据标系统的具体情况选择合适的版本。 其次,需要进行环境准备。包括设置开发环境、安装所需的编译器和调试工具等。同时,还需配置相关的驱动程序,以便emwin能够与标系统的硬件进行正确的交互。 接下来,需要进行源代码的移植。emwin5.24提供了丰富的API接口,可以用于嵌入式系统的图形界面开发。移植的关键就是将这些API接口与标系统的硬件平台和操作系统进行适配,确保其能够在标系统上正常运行。 在进行移植的过程中,还需要进行调试和测试,以确保移植后的emwin5.24能够稳定运行,并且具备所需的功能和性能。 最后,移植完毕后,需要对移植结果进行验证。可以使用一些示例程序或者自行开发的应用程序,进行功能测试和性能测试,确保emwin5.24标系统上的正常运行。 总结起来,移植emwin5.24版本是一个比较复杂的过程,需要深入了解标系统的硬件平台和操作系统,并进行相关的配置和适配工作。通过逐步移植、调试和测试,最终达到在标系统上稳定运行的标。 ### 回答2: emWin是一款嵌入式图形库,可以用于在小型处理器和嵌入式系统上实现用户界面。而emWin 5.24移植,则是指将emWin 5.24图形库移植到特定的嵌入式系统或平台上。 emWin 5.24移植的步骤如下: 1. 首先,需要了解标嵌入式系统的硬件架构和操作系统。例如,嵌入式系统可能采用ARM Cortex-M处理器和FreeRTOS操作系统。 2. 接下来,下载emWin 5.24图形库,并阅读其文档以进行进一步的了解和学习。 3. 在移植前,需要对emWin库进行配置。根据标嵌入式系统和平台的特性,设置相应的选项,如处理器类型和操作系统。 4. 在嵌入式系统上创建一个新的工程,并将emWin库的源文件和头文件添加到工程中。 5. 编译和链接工程,生成可执行文件。在这个过程中,可能需要根据具体的嵌入式系统进行适当的优化和配置。 6. 在代码中调用emWin图形库的API函数以实现相应的功能,如绘制图形、创建窗口、显示文字等。 7. 配置并连接显示设备,以便在嵌入式系统上能够正确显示emWin图形库的输出内容。 8. 最后,在嵌入式系统上运行程序,测试和验证emWin图形库的功能和性能。 emWin 5.24移植的过程中可能会遇到一些挑战,如处理器架构的兼容性、操作系统的适配性以及使用其他外设的问题。但通过正确的配置和调试,可以成功将emWin 5.24图形库移植到标嵌入式系统上,并实现所需的用户界面。 ### 回答3: emWin5.24移植是指将emWin5.24图形库移植到特定的硬件平台上,使之能够在该硬件上运行和显示图形界面。emWin5.24是一款专业的嵌入式图形库,为嵌入式设备提供了快速、灵活和高效的图形显示功能。 emWin5.24移植的具体步骤如下: 首先,需要了解标硬件平台的特性和规格,包括硬件架构、处理器型号、内存大小等。 其次,需要根据标硬件平台的特性选择适当的编译器和开发环境,并配置好相关的开发工具。emWin5.24支持主流的编译器和开发环境,如Keil、IAR等。 然后,根据标硬件平台的内存大小和存储结构,进行内存管理的设置。emWin5.24需要分配一定的内存空间来存储图形数据和图形对象,根据系统需求进行适当的内存分配。 接下来,需要根据标硬件平台的显示设备类型和接口进行显示驱动的编写。emWin5.24提供了丰富的显示驱动接口,可以根据硬件平台的特点进行适配和调整。 最后,需要将emWin5.24的源代码和相关的库文件添加到项中,并进行编译和链接。在编译过程中需要注意设置正确的编译选项和链接参数,确保程序能够正确地生成和运行。 总的来说,emWin5.24移植是一个相对复杂的过程,需要针对具体的硬件平台进行适配和调整。通过合理的配置和设置,可以将emWin5.24成功地移植到标硬件平台上,为嵌入式设备提供强大的图形显示功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值