华为笔试

1.题目描述:输入一个字符串,含有括号(大括号,小括号,中括号),数字和字母,数字(n)之后必跟一个括号(测试用例里的括号都是匹配的),代表括号内的字符串重复(n)次。括号里可以有嵌套,即括号里含有括号。现在将输入的字符串逆序展开;
输入描述:字符串,例:abc3(A)
输出描述:字符串,例:AAAcba

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace  std;
bool kuohao(string str)
{
	if (str.find("{") != -1 || str.find("[") != -1 || str.find("(") != -1)//str.find返回值为第一次查询到的位置坐标
		return true;//表示有括号
	else return false;//无 
}
string de(int left, int right, string str)
{
	int time = (int)(str[left - 1] - '0');
	string temp(str.begin() + left + 1, str.begin() + right);
	for (int i = 1; i < time; ++i)
	{
		for (int j = 0; j < temp.size(); ++j)
			str.insert(str.begin() + right + j + 1, temp[j]);//再rigt后插入数据
	}
	//删除
	str.erase(str.begin() + right);//为了不影响顺序倒着删除
	str.erase(str.begin() + left);
	str.erase(str.begin() + left - 1);
	return str;
}
int main()
{
	string str;
	while (cin >> str)
	{
		//首先输入判断有无大小中括号
		while (kuohao(str))
		{
			int left;
			int right;//记录坐标位置
			int len = str.size();
			//依次查询 { [(
			if (str.find("{") != -1)//有大括号
			{
				left = str.find("{");
				right = str.find("}", left);//这里只暂时考虑只有一位数字的情况
				str = de(left, right, str);
			}
			else if (str.find("[") != -1)
			{
				left = str.find("[");
				right = str.find("]", left);//这里只暂时考虑只有一位数字的情况
				str = de(left, right, str);
			}
			else if (str.find("(") != -1)
			{
				left = str.find("(");
				right = str.find(")", left);//这里只暂时考虑只有一位数字的情况
				str = de(left, right, str);
			}
		}
		reverse(str.begin(), str.end());
		cout << str << endl;
	}
	return 0;
}

2.题目描述
王强今天很开心,公司发给N元的年终奖。王强决定把年终奖用于购物,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:
主件 附件
电脑 打印机,扫描仪
书柜 图书
书桌 台灯,文具
工作椅 无
如果要买归类为附件的物品,必须先买该附件所属的主件。每个主件可以有 0 个、 1 个或 2 个附件。附件不再有从属于自己的附件。王强想买的东西很多,为了不超出预算,他把每件物品规定了一个重要度,分为 5 等:用整数 1 ~ 5 表示,第 5 等最重要。他还从因特网上查到了每件物品的价格(都是 10 元的整数倍)。他希望在不超过 N 元(可以等于 N 元)的前提下,使每件物品的价格与重要度的乘积的总和最大。
设第 j 件物品的价格为 v[j] ,重要度为 w[j] ,共选中了 k 件物品,编号依次为 j 1 , j 2 ,……, j k ,则所求的总和为:
v[j 1 ]*w[j 1 ]+v[j 2 ]*w[j 2 ]+ … +v[j k ]*w[j k ] 。(其中 * 为乘号)
请你帮助王强设计一个满足要求的购物单。

输入描述:
输入的第 1 行,为两个正整数,用一个空格隔开:N m

(其中 N ( <32000 )表示总钱数, m ( <60 )为希望购买物品的个数。)

从第 2 行到第 m+1 行,第 j 行给出了编号为 j-1 的物品的基本数据,每行有 3 个非负整数 v p q

(其中 v 表示该物品的价格( v<10000 ), p 表示该物品的重要度( 1 ~ 5 ), q 表示该物品是主件还是附件。如果 q=0 ,表示该物品为主件,如果 q>0 ,表示该物品为附件, q 是所属主件的编号)

输出描述:
输出文件只有一个正整数,为不超过总钱数的物品的价格与重要度乘积的总和的最大值( <200000 )。
示例1
输入
复制
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
输出
复制
2200

#include<iostream>
#include<vector>
using namespace std;
//依赖的01背包问题 最多两个附件
int max(int a, int b)
{
	return a > b?a:b;
}
int main()
{
	int n, m;//n=总钱数 m=物品个数
	while (cin>>n>>m)
	{
		n = n / 10;
		vector<vector<int> > dp( m + 1, vector<int>(n + 1,0));//定义为m+1*n+1大的数组,元素为0,n/10因为单价都是10的倍数 节约空间
		vector<vector<int> > value(m + 1, vector<int>(3, 0));//单件
		vector<vector<int> > weight(m + 1, vector<int>(3, 0));//单价*重要程度
		int v, p, q;//价格,重要程度,主件/附件
		for (int i = 1; i <= m; ++i)//存入所有信息
		{
			cin >> v >> p >> q;
			v /= 10;
			p = v * p;
			if (q == 0)//主件
			{
				value[i][0] = v;
				weight[i][0] = p;
			}
			else if (value[q][1]==0)
			{
				value[q][1] = v;
				weight[q][1] = p;
			}
			else
			{
				value[q][2] = v;
				weight[q][2] = p;
			}
		}
		//开始动态规划
		for (int i = 1; i <=m; ++i)
		{
			for (int j = 1; j <=n  ; ++j)
			{
				dp[i][j] = dp[i - 1][j];//如果不放入	
				if (value[i][0] >0)
				{
					
					if (value[i][0] <= j)//价格不超过
					{
						int t = max(dp[i][j], dp[i - 1][j - value[i][0]] + weight[i][0]);//比较放入与不放入谁的值更大
						dp[i][j] = t;
					}
					
					if (value[i][0] + value[i][1] <= j)//价格不超过
					{
						int t = max(dp[i][j], dp[i - 1][j - value[i][0] - value[i][1]] + weight[i][0] + weight[i][1]);//比较放入与不放入谁的值更大
						dp[i][j] = t;
					}
					if (value[i][0] + value[i][1] + value[i][2] <= j)//价格不超过
					{
						int t = max(dp[i][j], dp[i - 1][j - value[i][0] - value[i][1] - value[i][2]] + weight[i][0] + weight[i][1] + weight[i][2]);//比较放入与不放入谁的值更大
						dp[i][j] = t;
					}
				}
			}
		}
		cout << dp[m][n]*10 << endl;;
	}
	return 0;
}

3.动态规划 最长递增子串
题目描述
Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗?
样例输入
6
2 5 1 5 4 5
样例输出
3

#include<iostream>
#include<vector>
using namespace std;
int main()
{
	int num;
	while (cin>>num)
	{
		vector<int> a(num);
		vector<int> dp(num, 1);
		for (int i = 0; i < num; ++i)
			cin >> a[i];
		int max = 0;
		for (int i = 1; i < num; ++i)
			for (int j = 0; j < i; ++j)
			{
			if (a[i]>a[j] && dp[i] < dp[j] + 1)
				dp[i] = dp[j] + 1;
			if (max < dp[i])
				max = dp[i];
			}
		cout << max << endl;
	}
	return 0;
}

4.匈牙利算法
若两个正整数的和为素数,则这两个正整数称之为“素数伴侣”,如2和5、6和13,它们能应用于通信加密。现在密码学会请你设计一个程序,从已有的N(N为偶数)个正整数中挑选出若干对组成“素数伴侣”,挑选方案多种多样,例如有4个正整数:2,5,6,13,如果将5和6分为一组中只能得到一组“素数伴侣”,而将2和5、6和13编组将得到两组“素数伴侣”,能组成“素数伴侣”最多的方案称为“最佳方案”,当然密码学会希望你寻找出“最佳方案”。
输入:
有一个正偶数N(N≤100),表示待挑选的自然数的个数。后面给出具体的数字,范围为[2,30000]。
输出:
输出一个整数K,表示你求得的“最佳方案”组成“素数伴侣”的对数。
输入:4
2 5 6 13
输出:2

解题思路:
本文采用图论中的匈牙利算法。因为 偶数+偶数=偶数
奇数+奇数=奇数
偶数+奇数=奇数
且所有的偶数不是素数,因此只对奇数进行判断
所以,将输入的数分为偶数(even,代码中打错了= =)与奇数(odd)两组。
用pick[]存放下even+odd之和是否为素数的结果
用x[]存放odd中的数据是否匹配。-1=未匹配 1=匹配
用y[]存放odd中与even中匹配数的索引
本程序的思想是对even中的数进行历遍,并且每一次都假设odd中的数据没有匹配成功(初始x[],但是不改变y[])

// 利用匈牙利算法
#include<iostream>
#include<vector>
using namespace std;
bool isprime(int a)
{
	for (int i = 2; i*i <= a; ++i)
	{
		if (a%i == 0)
			return false;
	}
	return true;
}

bool f(int index, vector<int> &x, vector<int> &y, vector< vector<int> > pick)
{
	for (int j = 0; j < x.size(); ++j)
	{
		if (pick[index][j] == 1 && x[j] == -1)
		{
			x[j] = 1;//表示匹配
			if (y[j] == -1 || f(y[j],x,y,pick) )//如果odd中的数已经匹配,将其强行占领 
			{//寻找与之匹配的even是否还要其他odd匹配
				y[j] = index;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	int n;
	while (cin >> n)
	{
		/*vector<int> num(n);
		for (int i = 0; i < n; ++i)
		cin >> num[i];*/
		//将输入的数分为偶数、奇数两部分 偶数+奇数=奇数 
		//排除掉:偶数+偶数=偶数 奇数+奇数=偶数 偶数不可能为素数
		vector<int> enve;//偶数
		vector<int> odd;//奇数
		int temp;
		for (int i = 0; i < n; ++i)
		{
			cin >> temp;
			if (temp % 2 == 0)
				enve.push_back(temp);
			else
				odd.push_back(temp);
		}
		//构建出偶数与奇数的关系
		vector< vector<int> > pick(enve.size(), vector<int>(odd.size()));
		for (int i = 0; i < enve.size(); ++i)//为质数,初始化列表
		{
			for (int j = 0; j < odd.size(); ++j)
			{
				if (isprime(enve[i] + odd[j]))//和是否为素数
				{
					pick[i][j] = 1;//表示和为素数
				}
				else
					pick[i][j] = 0;
			}
		}
		int len1 = enve.size();
		int len2 = odd.size();
		int count = 0;
		//vector<int> x(enve.size(), -1);//-1无匹配
		vector<int> y(odd.size(), -1);//-1无匹配
		for (int i = 0; i < len1; ++i)
		{
			vector<int> x(odd.size(), -1);//每一次历遍先假设-1无匹配
			if (f(i, x, y, pick))
				count++;
		}
		cout << count << endl;		
	}
	return 0;
}

5.有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?
输入:9 输出:34
法一:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	int  month;
	while (cin>>month)
	{
		int a=0;//三个月大
		int b=0;//两个月
		int c=1;//一个月
		while (--month)
		{
			a += b;
			b = c;
			c = a;
		}
		cout << a + b + c << endl;
	}
	return 0;
}

法二:递归

#include<iostream>
#include<cstdio>
using namespace std;
int f(int month)
{
	//思路推导:
		//时间轴(月):1 2 3 4 5 6 7
	//	兔子数量: 1 1 2 3 5 8 13
		//发现是一个斐波那契数列,所以公式为f(n) = f(n - 1) + f(n - 2);
	int ans ;
	if (month == 1||month==2)
		return ans = 1;
	else
		ans = f(month - 1) + f(month - 2);
	return ans;
}
int main()
{
	int  month;
	while (cin>>month)
	{
		int ans = f(month);
		cout << ans;
	}
	return 0;
}
专业面试我的技巧和经验: 一、 巧妇难为无米之炊,事前做一些功课是必须的,把自己学习过的和应聘岗位相关的内容复习下,比如性能与算法岗位:本科电子信息工程和通信工程这些课程肯定学过,通信原理,信息论和编码,信号与系统,数字信号处理,复习一下掌握大概的轮廓一个星期应该差不多可以搞定. 二、 善于引导面试官,比如当面试官问到什么问题不懂的时候,避免连问几个都不懂,可以尝试这么说:我***方面的知识比较匮乏,不是很了解,但是我对***的知识还是比较熟习,我觉得***的知识在我们华为性能与算法工程师必须要掌握的吧。以我面试为例,面试问我3G和4G的关键技术,已经这些关键技术的基本原理,我是做雷达信号处理的,确实不懂。我就和面试官说:对不起,因为研究生期间主要做的雷达信号处理的工作,我对移动通信的知识了解甚少,但是我对移动通信的基础只是比如通信原理和调制解调技术还有一定的了解(当然这都是我事先复习好的),我觉得无论什么类型的通信技术都离不开这些基本的理论。接着面试官就让我说信源编码和信道编码的作用已经他们通常采用的方法,当然我也就能对答如流了。所以,引导很重要。 三、 专业面试对自己简历上不要为了蒙骗面试官,写的项目自己捡不熟悉,对简历上的东西一问三不知,语言表达不清楚,说不半天不能告诉面试官你做的工作内容和意义,这个很不好。 群面 一般10-14个人,看当天应聘的人数而定,分2组,一个话题,让排序之类的,或者辩论之类的,不同的组会抽到不同的问题,不同的地方也会有不同的问题,在这里把问题说出来没什么意义,这一轮会有很多意想不到的情况,比如这组我本来不是选为组长,但是在做总结的时候面试官让我做总结,或者突然问你刚才某某同学说的话你同意吗,或者突然说你今天脸色好像不好看之类的,所以灵机应变才是王道。群面一般要自我介绍,自我介绍要简短,不要说太多,我建议按以下几个方面说,自己学校专业、来自哪里、然后说自己学习,主要稍微说下自己的项目,说下名字就OK了,然后说自己做项目获得成果,比如发表文章,专利和之类的。然后说自己优点和缺点,一般情况下优点缺点都要说,而且我觉得最好优点缺点自己多准备几个,免得到时候你要说的前面的人都说了,就像我们这组:我开始说缺点的时候说我性格比较急,做什么事情都想快点做完,午觉也不睡,但是经常适得其反,中午不谁觉,下午就工作效率低。后面好几个同学说的时候都这么说了,惹的面试官说,你们重复一个东西说。说缺点的时候大家要慎重,不要说和自己工作相关的缺点,比如我们那个组一个同学说:我的缺点就是比较随性,重要场合经常穿拖鞋为此挨了不少批评。 面试官:。。。。(前面省略了一些),你这种随行的行为有同学提醒过你吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值