華爲2021屆軟件類校園招聘筆試題題解

第一題很簡單,忘了是什麼題了。

第二題:驗證報文

難點在於進制的轉換和輸入輸出,python對於十六進制的存儲是0x__,比如5就是0x5,而C和C++就是5,這裏稍有不同,當時我摸不清python版本的輸入格式到底是什麼,因爲python只能用readline()的形式直接從命令行得到整條輸入,再進行解析,這裏就糾結到底是0x5還是5,想的腦子疼,(筆試結束後朋友提醒牛客網好像可以輸出樣例輸入),就沒寫這道題。

題目:報文流T由報文組成,每個報文以十六進制存儲,開始符是5a,結束符也是5a,在結束符之前,用一個字節來存儲報文長度域(不包含開始、結束以及長度域本身),報文內如果遇到5a,5b兩種字符,轉義成5b ba和5b bb,但長度不變。兩個報文合併時,可以將中間的5a省去一個,用一個5a同時作爲上一個報文的結束符和當前報文的開始符。

例如5a 06 5b ba 37 5b bb 44 05 5a 12 34 5b ba 03 5a報文流由兩個報文組成

1:5a 06 5a 37 5b 44 05 5a

2:5a 12 34 5b 03 5a

問題:現在有一個報文流,裏面有部分報文是錯誤的,(可能是沒轉義,可能是長度域錯誤等),需要剔除錯誤的報文,並返回剩餘正確的報文流。

思路:

一:一個十六進制佔1個字節,先將輸入的十六進制數據流轉爲整數存在數組裏(考察輸入)

二:遍歷,將兩個5a之間的數組放進子函數,子函數計算這個數組的長度(注意將轉義字符看做一個字節),跟長度域比較,不相等就不管,相等就放入結果數組裏,

三:將結果數組按照十六進制輸出即可。(這裏注意結果要補0,5要輸出成05,用print('02x'%input)即可)

挺可惜,我當時被輸入輸出整的有點煩,也是因爲LeetCode並不需要處理輸入輸出,所以平時練得實在不多。

 

第三題:最優子序列

題目:現有一個序列長度爲m,我們要將其分解成k個子序列,1<=k<=m<=500,序列由整數組成,整數小於10^7。要求這k個子序列和的最小值儘可能大,在有多解的情況下,優先s(1)序列最大,如果s(1)相同,則s(i+1)依次往下排。

例如:

100 200 300 400 500 600 700 800 900

k=3的情況

我們需要輸出: 100 200 300 400 500 / 600 700 / 800 900

這樣的劃分是最優的,最小值600+700=1300是能劃分的最大值

思路:

這裏很重要的是我們需要找出那個最優的最小值來劃分序列。查找自然就要用二分查找法啦,令X爲我們要找的劃分值,那麼我們需要用二分來找X。二分查找自然需要low和high,這裏low=0無疑問,數組和最大值爲500*10^7,所以high就是5e9。

那麼如何判定一次二分之後mid該往哪邊去呢?

試想,我們構建一個函數f,使得x能劃分時,f(x)=1,不能劃分時f(x)=0,那麼我們需要找的X正好就是這個函數定義域的分界點,任何x<X使得f(x)=1,任何x>X使得f(x)=0,所以mid往哪邊走,由函數f返回值來確定。

接下來構建函數f。首先,我們根據x來劃分序列,每個子序列必須要大於x。f(x)=0時,也就是x太大,最後劃出來區域數量小於k。f(x)=1,則x存在,可以劃分出k個區域(並不保證最優,但保證存在)

上代碼

def make_parts(a,k,x):
    parts=[]
    num_part=0
    i=len(a)-1
    #從後往前遍歷,目的是保證前面的子序列和能更大
    while i>=0:
        tmp_sum=0
        part=[]
        j=i
        #劃分子區域
        while j>=0 and tmp_sum<x:
            part.append(a[j])
            tmp_sum+=a[j]
            j-=1
        i=j
        #x過大,直接返回0
        if tmp_sum<x:
            return None
        num_part+=1
        #如果x過小,那麼劃分完後會有多餘的區域沒有併入,將剩餘區域併入s(1)序列
        if num_part==k:
            while i>=0:
                part.append(a[i])
                i-=1
        parts.append(part)
    #x偏大,不能劃分k個區域
    if num_part<k:
        return None
    return parts

子函數構建完成,外面套個二分查找即可,查找到最優值X後,再用子函數分一次X就是答案。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章