2023年聯發科程式設計比賽 傑克船長的煩惱

2021-08-21 20:58:20 字數 3544 閱讀 6402

首先看題目要求:

傑克船長這次運氣不錯,搶到了一大堆金幣。但他馬上又開始發愁了, 因為如何給大家分金幣,一直都是件不容易的事,每次傑克船長都要頭疼好幾天。

關於分金幣,海盜的行規是這樣的:

每次行動,船長會根據各個海盜的表現記功,事後**行賞,給大家分金幣。

分戰利品的時候,海盜們會隨意的站成一排,船長給每個人發一袋金幣。袋子裡的金幣數目有多有少,但船長保證每個海盜至少會分到一枚金幣。

拿到金幣後,相鄰的兩個海盜會互相比較。如果其中乙個功勞高些,那他的金幣必須多一些,如果兩個人分數一樣,他們的金幣必須一樣。否則,海盜們就覺得不公平,要**,甚至造反。

怎麼樣才能用最少的金幣讓大家都滿意呢? 領導這幫海盜可不輕鬆。

聽說這次比賽中有一位將來要成為海賊王的男人,傑克船長相信他一定能解決這個麻煩。

在程式當前目錄下存在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 同比增...