百度笔试题分享

有四种不一样的分子,a,b是单原子分子,c,d是双原子分子。给出构成这四种分子的原子质量。用这四种分子构成一个元素,给定元素质量,求最多能够用多少个分子。ios

思路:其实机器解题和人解题是一个思路,遇到这种问题,人怎么解决呢。就是尝试。算法

这里有两个算法思想:动态规划和贪心算法。编程

动态规划:将问题分部分解决,且最好前面被解决的问题可以被后面屡次使用,那就把前面解决了的问题结果存起来,以备后面使用,从而提升效率。spa

贪心算法:每次先试最有可能出现解的路径。PS;事实上,我在生活中很是不会使用贪心算法。好比去找一本书,命名以为最有可能在第三层,确要从第一层找起,这样作事效率就低。改正之~编程反过来能启发生说。code

这个问题能够写为f(a,b,c,d,x)排序

a,b,c,d分别为四种分子的质量,x为待合成的化合物的质量。递归

那么f(a,b,c,d,x) = f(a,b,c,d,x - a) + 1 或者=f(a,b,c,d,x - b) + 1 或者=f(a,b,c,d,x - c) + 1 或者=f(a,b,c,d,x - d) + 1 hash

那么f(a,b,c,d,x - b)是否是也能够按照以上方法分解了呢,直到最后发现x为0了,那么恭喜,试出来一个,若是小于0了,那不行,得从新试。it

聪明的你应该发现,递归就能够解决问题io

以上就是遍历,若是用一个全局变量记录结果,会知道最大会返回多少,那就是解。

可是咱们用贪心,先将,a,b,c,d进行排序,先对质量小的进行递归,那么,是否是第一个被试出来来的,就是解呢。这样计算量就会大大下降。


若是这个题改为最多能有多少个原子,会复杂一点,由于要创建分子质量和原子数(或者原子质量)之间的hash表,用multimap就能够解决。这样作的目的是为了可以排序,实现贪心。

注意:不能用map,由于不容许键值相同的元素出现。

下面贴出最多原子数的代码:

#include <iostream>
#include<map>

using namespace std;
int funCore(multimap<int,int> &m ,int massX);
int fun(int massA,int massB,int massC,int massD ,int massX);
int main() {
	//int res = fun(5,8,5,3,23);
	map<int,int> m;
	m.insert(make_pair(1,1));
	m.insert(make_pair(1,2));
	int res = fun(5,8,5,3,23);
	cout << res;
	return 0;
}
//summary:生成可用的hashmap,以单原子质量为键值,分子质量为value
//parameters:
//massA:原子A的质量
//massA:原子B的质量
//massA:原子C的质量
//massA:原子D的质量
//massX;待构成元素的质量
//return:最多的原子数。
int fun(int massA,int massB,int massC,int massD ,int massX){
	multimap<int,int> numMap;
	numMap.insert(make_pair(massA,massA));
	numMap.insert(make_pair(massB,massB));
	numMap.insert(make_pair(massC,massC * 2));
	numMap.insert(make_pair(massD,massD * 2));
	return funCore(numMap,massX);

}
//summary:递归计算最多原子数。算法思想是,动态规划,就是将问题先解决一部分,并把结果存储下来。递归提供了存储的手段
//具体就是funCore(multimap<int,int> &m ,int massX) = 选一个分子*单分子原子数 + funCore(multimap<int,int> &m ,int massX - 选择的分子数量)
//还有一个算法思想是,贪心算法,先选原子质量小的分子,multimap可以对元素按键值进行从小到大排序,注意不能用map,map不容许键值重复
int funCore(multimap<int,int> &m ,int massX){
	if(massX == 0)
		return 0;
	if(massX < 0)
		return -1;
	for(multimap<int,int>::iterator it=m.begin();it!=m.end();++it){
		int nA = funCore(m,massX - it->second);
		if(nA >= 0)
			return nA + it->second / it->first;
	}
	return -1;
}