首先看題目要求:
傑克船長這次運氣不錯,搶到了一大堆金幣。但他馬上又開始發愁了, 因為如何給大家分金幣,一直都是件不容易的事,每次傑克船長都要頭疼好幾天。
關於分金幣,海盜的行規是這樣的:
每次行動,船長會根據各個海盜的表現記功,事後**行賞,給大家分金幣。
分戰利品的時候,海盜們會隨意的站成一排,船長給每個人發一袋金幣。袋子裡的金幣數目有多有少,但船長保證每個海盜至少會分到一枚金幣。
拿到金幣後,相鄰的兩個海盜會互相比較。如果其中乙個功勞高些,那他的金幣必須多一些,如果兩個人分數一樣,他們的金幣必須一樣。否則,海盜們就覺得不公平,要**,甚至造反。
怎麼樣才能用最少的金幣讓大家都滿意呢? 領導這幫海盜可不輕鬆。
聽說這次比賽中有一位將來要成為海賊王的男人,傑克船長相信他一定能解決這個麻煩。
在程式當前目錄下存在execute.stdin檔案,程式從execute.stdin中取得輸入資料。
execute.stdin中存放著n(n<100)個十進位制正整數,數字之間用空格格開。
每個數字都代表某個海盜的功勞,值範圍為(1, 100)。
輸出乙個正整數,代表讓所有海盜都滿意的最少的金幣數。
execute.stdin內容:1 3 3 2
預期輸出:6
說明:符合要求的金幣分法是 1 2 2 1
題目解讀:就是有一串數,給這串數種的每個數附乙個權,權盡量小,但是兩個相鄰的數,本身大的數,其權必大於其相鄰的小的數。
思路,採用排序樹的思路,不過不是二叉樹,每個節點只有左子樹或者只有右子樹,左子樹《父節點,右子樹》=父節點,父節點的權值等於左子樹深度,或者等於前乙個權加1。
圖中主要介紹了這種思想,注意右側樹葉,沒有左孩子也沒有右孩子,要麼等於父節點,要麼等於父節點+1。
最複雜的是中間的右分支,相等的情況都出現這裡。盡量向父節點靠,即如果有乙個節點的值等於父節點,那麼他的權應該盡量等於父節點,但是如果這個節點是右側的轉折點,那麼父節點要想該節點靠,即權等於該節點。
演算法如下:
#include
#include
#include
using namespace std;
//基於二叉排序樹
typedef struct sorttree
}*stree;
stree createstree(vectorvec)
else
if (vec[i] >= vec[i - 1])//相等的情況放在右子樹,因為我們用左子樹深度判定金幣
}ptree->lchild = null;
ptree->rchild = null;
return tree;
}void treeprint(stree tree)
}//右子樹比左子樹大1,左子樹深度+1是根的金幣
//我們的資料要麼有左子樹要麼有右子樹,不可能同時有左右子樹
int deep(stree tree)
num++;
return num;//左子樹深度
}bool parent_has_lchild(stree tree ,int i)//搜尋i節點的父節點是否有左子樹
else
if (tree->rchild)
}if (tree->lchild)
else
return false;
}bool father_equal_child(stree tree, int i)
if (tree->lchild)
else
if (tree->rchild)
}return false;
}vectordeepjihe(stree tree,int length)
else
if (m_deep->lchild && m_deep != tree && !parent_has_lchild(tree,i))//不是頭節點,有左孩子,要判斷左孩子深度與父節點的大小,如果大,就=深度,否則,=父節點+1
else
}else
if (m_deep->lchild && m_deep != tree && parent_has_lchild(tree, i))
else
if(m_deep->rchild)
else
else
if(!parent_has_lchild(tree, i))}}
else
if (m_deep->rchild == null && m_deep->lchild == null && parent_has_lchild(tree,i))//父節點有左孩子
else
if (m_deep->rchild == null && m_deep->lchild == null && !parent_has_lchild(tree, i))
}return vec;
}//判斷當前節點是否有左孩子
bool cur_has_lchild(stree tree, int i)
else
if (tree->rchild)
}if (tree->lchild)
else
if (tree->rchild)
return false;
}bool is_right_turn(stree tree, int i)
else
return false;
}bool is_left_turn(stree tree, int i)
else
return false;
}//這個函式的作用是修正陣列,從根節點依次判斷,如果是轉折點(父節點有右孩子,自己有左孩子),
//那麼都得向這個方向靠攏,我們的樹把相等的放在了右孩子上了
vectorhasequal(stree tree, vectorvec,vectorvec1)
else
if (!is_right_turn(tree, i) && is_left_turn(tree, i - 1))//當前節點不是右轉折點,前乙個節點是左轉折點
else}}
return vec2;
}int sum(vectorvec)
return sum;
}int main()
ifs.close();
stree tree = createstree(vec);
vectorvec1;
vec1 = deepjihe(tree, vec.size());
vectorvec2;
vec2 = hasequal(tree,vec,vec1);
int sump = 0;
sump = sum(vec2);
cout << sump << endl;
return 0;
}ps:本人是演算法小白,研究方向也不再此,只是想出來乙個小想法並且進行了實現,有不好之處請指教。
聯發科筆試題程式設計部分
1 實現鍊錶的逆置 node inverselinklist node head p1 head p2 p1 next while p2 head next null head p1 return head 2 用普通演算法實現兩個有序鍊錶的合併 node mergelinklist node he...
聯發科程式設計大賽 第一題最大序列和
最大序列和 給出乙個整數序列s,其中有n個數,定義其中乙個非空連續子串行t中所有數的和為t的 序列和 對於s的所有非空連續子串行t,求和最大的子串行。以上說明中 n為正整數,n 1000000,結果序列和在範圍 2 63,2 63 1 以內。輸入說明 在程式當前路徑下存在檔案execute.stdi...
聯發科2023年首月營收6 46億美元
2月15日訊息,據台灣 報道,智慧型手機晶元解決方案提供商聯發科稱,2016年1月份該公司實現綜合收入213.3億元新台幣 約合6.46億美元 較去年最後乙個月增長15.2 較去年同期增長22.1 2015年12月份,聯發科下滑至不足200億元新颱,為185.20億元新台幣,環比降低11.6 同比增...