百度筆試題分享

有四種不一樣的分子,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;
}