開考看A題,傻呵呵的推了4遍式子才推出正確的,四遍過A題(我可能是最後一個過A題)。
然後看B題,最開始像個傻子一樣愣了半天,然後恍然大悟。
細節要人命,有一個邊界沒設好,兩遍A
然後看C題,(可能進入狀態了),看完題就會了。
細節還是要人命,可能是負數,然後我的前綴最大值數組初值是零,兩遍A
然後還剩1h,開始想D題,想了一下,覺得第二問比較好做,先敲了一下,發現有問題,然後重推,大概15min,想到了做法,開始敲,15min左右敲完,WA on test 2,當時覺得自己思路比較混沌,就去看了一下E題,猜了一個結論,錯了,順手寫了一個暴力(算是爲後面訂題做了個鋪墊)。
回頭調D題,然後卡着時間調完WA on test 6。(然而思路是對的。。)
最後A三題
題解部分
A題:
隨便推一推,可得答案就是n
B題:
就是在數軸上兩點間的距離,先排序,然後在前面取一個,後面取一個。
如:
數列
排完序後:
調整完後即爲:
C題:
首先,貪心的,我們讓要調整的數調整爲與前綴最大值相等,並且顯然這可以做到,而且是最優的
由於我們只在意最大的,那麼我們只需要記錄與前綴最大值相差最多的那個差值就好了。
找到後就只要看一下他最多要幾位二進制才能表示就好了。
重頭戲開始
D題:
問題有兩部分,最多和最少
最少比較好想
首先如果兩個葉子之間邊數是偶數,那麼我們安排一樣的邊權顯然是最優的,此時答案是1
然後考慮是奇數的時候
一種肯定是不夠的,那麼考慮兩種可不可以,顯然也不行(注意邊權必須是正整數),而三種是可以的。
下面具體說明原因:
如果是兩種邊權,那麼一種邊權的個數肯定是偶數,另一種是奇數,那麼這顯然是不行。
如果是三種邊權,然後設邊數是m,那麼前m-2條邊設爲第一種權值(假設是a),第m-1條邊設爲第二種權值(假設是b),然後第m條邊的權值設爲a^b就好了
那麼我們只要判斷是否有兩個葉子之間的邊數是奇數就好了,有奇數答案就是3,沒有就是1
這個判斷可以通過黑白染色輕易做到,下面是圖解:
上圖中,既有顏色是黑色的點,又有顏色是白色的點,那麼就存在邊數爲奇數一對葉子,如果所有葉子只有一種顏色那麼就沒有邊數爲奇數一對葉子
下面是這段的代碼(隨手打出來的,不保證正確性,正確的代碼會在最後總的放出):
然後考慮最多。
先想一條鏈,我們顯然可以給每一條邊都安排上不同的權值(前面的權值可以隨便安排,只要在最後一個安排和前面異或值相等的數就好了)
那麼對於所有分叉,都是一樣的,我們都可以安排不同的值,那麼現在似乎看起來答案就是總邊數。
然後我們通過樣例觀察法,發現我們上面的猜想是錯的,因爲有一些情況,邊權不得不相等,看下圖
這兩條邊是必須相等的,我們再看一個例子
這個圖裏用相同的顏色標註的邊都是必須相等的
那我們可以得到一個結論,如果有兩個葉子之間只有兩條邊,那麼這兩條邊必須相等。
換句話說,如果一個點的兒子裏有兩個以上的葉子,那麼我們就要把答案減去(兒子個數-1)(初始答案爲邊數)
下面上這段的代碼(隨手打出來的,不保證正確性,正確的代碼會在最後總的放出)
最後還有一點要補充的,題目給出的是無根樹,所以要由我們去確定一個根,這個根其實可以隨便選,但是要滿足一個它本身不是葉子
總代碼:
E題
(最後一題,也是最難講的一題)(所以咕咕咕)
先講總思路:打表找規律。
爲了方便理解並且之後寫代碼,你可能需要一個形如這樣的暴力
我們先對這個代碼輸入20,看看前20組
好像沒看出什麼,那我們輸入100看一下
這時候只要細心看看,就會驚奇的發現每組數的第一個有着什麼規律,再細細想想,你就會發現第一個數是這樣排列的:。
雖然沒有全部打出來,但是我們有理由相信接下來是,不放心你大可以打出來看看。
我們把這個規律整理一下就是,每組的第一個數是這樣排列的:
(敲黑板)(接下來是腦洞時間)
這個規律和這個美妙的數字扯上關係了,那我們不如把這些數寫成二進制吧
爲了減少計算量,我們寫一下前面十組
然後我們可以看出很多東西,由於直接敘述太過累贅,我用顏色標明
根據上圖,我們可以清楚地看到當你得到了第一組{}({})之後,你可以根據這一組得到接下來四組
我們在上面已經對一組組的數又分了個組:
我們把這個規律整理一下就是,每組的第一個數是這樣排列的:
我們按第一個數的規律分了組(爲了不概念混淆之後稱之爲大組),結合剛剛發現的規律,也就是你得到當前這一大組的第一組,那麼你可以通過這一組得到下一大組的前四組(如果你得到了當前這一大組的第二組,那麼你可以通過這一組得到下一大組的第五組到第八組,以此類推)
然後我們看上面第一張圖的黑色部分
然後我們看第二張圖,關注第三大組的前四組(注意顏色標註)
觀察這四組的黑色部分
然後我們發現這與上面的黑色部分完全相等!
這說明每一組數的後兩位是有規律的,
我們可以通過看第一個數在二進制下後兩位是什麼來得出第二個數和第三個數後兩位是什麼
舉個例子:
假設我們要求第二個數
把寫成二進制是
我們發現後兩位是 , 那麼第二個數後兩位就是
然後把後兩位去掉變成 , 此時後兩位是 , 那麼第二個數後兩位的再後兩位就是
然後進行相同的操作(爲了方便敘述,設第一個數爲,第二個數爲),
=10001 ,=10+10=1010(此處的加號表示拼接)
=100 ,=00+1000=001010
=01 (不足兩位時補0),=10+001010=10001010=138
那麼現在來理一下思緒,給你一個,首先算出這個數屬於第幾組的第幾個,然後算出第一個數是多少,然後如果你要得到的是第二個數或第三個再用第一個數算出。
上代碼: