第八届蓝桥杯(软件类)决赛C/C++B组真题题解
題目結構
| 第一題 | 結果填空 | 15分 |
| 第二題 | 結果填空 | 47分 |
| 第三題 | 代碼填空 | 25分 |
| 第四題 | 程序設計 | 35分 |
| 第五題 | 程序設計 | 79分 |
| 第六題 | 程序設計 | 99分 |
第一題 36進制
-
問題描述
對于16進制,我們使用字母A-F來表示10及以上的數字。
如法炮制,一直用到字母Z,就可以表示36進制。
36進制中,A表示10,Z表示35,AA表示370
你能算出 MANY 表示的數字用10進制表示是多少嗎?輸出
輸出一個整數表示答案
-
解題思路
36進制。位權值為36。累加位權和即可。
-
代碼
-
答案
104025410402541040254
第二題 瓷磚樣式
-
問題描述
小明家的一面裝飾墻原來是 3×103\times103×10 的小方格。
現在手頭有一批剛好能蓋住222個小方格的長方形瓷磚。
瓷磚只有兩種顏色:黃色和橙色。
小明想知道,對于這么簡陋的原料,可以貼出多少種不同的花樣來。
小明有個小小的強迫癥:忍受不了任何2×22\times22×2的小格子是同一種顏色。
(瓷磚不能切割,不能重疊,也不能只鋪一部分。另外,只考慮組合圖案,請忽略瓷磚的拼縫)
顯然,對于 2×32\times32×3 個小格子來說,口算都可以知道:一共101010種貼法。
但對于 3×103\times103×10 的格子呢?肯定是個不小的數目,請你利用計算機的威力算出該數字。
輸出
輸出一個整數表示答案
-
解題思路
對于這道題,我們很容易就想到利用dfsdfsdfs暴力去解決,那么我們需要注意的就是如何去表示整個方格以及如何判斷是否符合要求并判重。 對于表示整個方格,我們可以用字符串來表示,也可以用二維數值數組來表示,那么這樣我們就需要說明各自代表的是什么,該題黃色我表示為111,未填表示為000,橙色表示為?1-1?1。那么對于判斷是否符合要求,直接累加2×22\times22×2的方格值即可,判斷是否模444為000。這很方便,我們也很容易證明,若方格值顏色相同,那么自然是模444為000的。再回到判重,我們可以將二維數值數組轉化為字符串放入setsetset中,也可以將二維數組轉化為111個值,這里采用二進制的權值,那么這樣我們總能保證不相同得到的和是不相同的。
-
代碼
-
答案
101466101466101466
第三題 希爾伯特曲線
-
問題描述
希爾伯特曲線是以下一系列分形曲線 Hn 的極限。我們可以把 Hn 看作一條覆蓋2n×2n2^n × 2^n2n×2n 方格矩陣的曲線,曲線上一共有 2n×2n2^n × 2^n2n×2n 個頂點(包括左下角起點和右下角終點),恰好覆蓋每個方格一次。
Hn(n > 1)可以通過如下方法構造:
- 將 Hn-1 順時針旋轉90度放在左下角
- 將 Hn-1 逆時針旋轉90度放在右下角
- 將2個 Hn-1 分別放在左上角和右上角
- 用3條單位線段把4部分連接起來
-
解題思路
題目分析已貼于代碼中,這道題主要就是理清題意即可。
-
答案
m-y+1
對于 Hn 上每一個頂點 p ,我們定義 p 的坐標是它覆蓋的小方格在矩陣中的坐標(左下角是(1,1)(1, 1)(1,1),右上角是(2n,2n)(2^n, 2^n)(2n,2n),從左到右是X軸正方向,從下到上是Y軸正方向),
定義 p 的序號是它在曲線上從起點開始數第幾個頂點(從1開始計數)。
以下程序對于給定的n(n<=30)n(n <= 30)n(n<=30)和p點坐標(x,y)(x, y)(x,y),輸出p點的序號。請仔細閱讀分析源碼,填寫劃線部分缺失的內容。
#include <stdio.h>long long f(int n, int x, int y) {//n代表的是方格矩陣Hn,大小為2^n*2^nif (n == 0) return 1;//由于遞歸到了H0,那么自然為1.int m = 1 << (n - 1);//即m=2^(n-1)次方。if (x <= m && y <= m) {return f(n - 1, y, x);//這里表明,如果x和y是屬于左下角的子矩陣,那么我們就遞歸去尋找,由于左下角的子矩陣是順時針翻轉的,那么我們需要更改x和y}if (x > m && y <= m) {//同理,這里則是右下角的子矩陣。根據前面的分析,這道題其實就易解了。注意這個子矩陣是逆時針翻轉過來的。//如果沒有翻轉,坐標是(x-m,y),現在需要翻轉,則為(m-y+1,m-(x-m)+1)//return 3LL * m * m + f(n - 1, ________________ , m * 2 - x + 1); // 填空return 3LL * m * m + f(n - 1, m-y+1 , m * 2 - x + 1); // 填空}if (x <= m && y > m) {//這里為左上角的子矩陣,那么我們需要加上已經過去了的m*m的序號。//這里坐標我們是需要更改的,因為我們遞歸到左上角的Hn-1矩陣了,那么坐標自然要更改。return 1LL * m * m + f(n - 1, x, y - m);}if (x > m && y > m) {//這里為右上角的子矩陣,那么我們需要加上已經過去了的2*m*m的序號。return 2LL * m * m + f(n - 1, x - m, y - m);} }int main() { int n, x, y;scanf("%d %d %d", &n, &x, &y); printf("%lld", f(n, x, y));//給定p點的坐標,輸出p點的序號。return 0; }第四題 發現環
-
問題重現
小明的實驗室有N臺電腦,編號1~N。原本這N臺電腦之間有N-1條數據鏈接相連,恰好構成一個樹形網絡。
在樹形網絡上,任意兩臺電腦之間有唯一的路徑相連。
不過在最近一次維護網絡時,管理員誤操作使得某兩臺電腦之間增加了一條數據鏈接,于是網絡中出現了環路。
環路上的電腦由于兩兩之間不再是只有一條路徑,使得這些電腦上的數據傳輸出現了BUG。
為了恢復正常傳輸。小明需要找到所有在環路上的電腦,你能幫助他嗎?輸入
第一行包含一個整數N。
以下N行每行兩個整數a和b,表示a和b之間有一條數據鏈接相連。
對于30%的數據,1<=N<=10001 <= N <= 10001<=N<=1000
對于100%的數據, 1<=N<=100000,1<=a,b<=N1 <= N <= 100000, 1 <= a, b <= N1<=N<=100000,1<=a,b<=N
輸入保證合法。輸出
按從小到大的順序輸出在環路上的電腦的編號,中間由一個空格分隔。
樣例輸入
5 1 2 3 1 2 4 2 5 5 3樣例輸出
1 2 3 5 -
解題思路
-
拓撲排序
我們都知道拓撲排序實際上僅能適用于有向無環圖的,那這里如果我們要強行應用在無向圖中,應該要注意什么?首先,現在入度為111和000的都是起點,而不再是以入度為000作為標志了,同樣,由于是無向圖,我們需要認為一條邊上的兩個頂點入度都需要增加。知道了這樣,實際上我們就可以處理了,最后沒有入隊的即是存在環的。
-
并查集處理連通+dfs查找環
并查集處理這道題其實是非常方便的,我們怎么判斷出現環了呢?即是當所加入的邊上的兩個頂點已經連通在一起了,我們如果再次連接就會出現環路。那么查找環也是一個問題,我們需要確定環路的起點和終點,而結束狀態則是起點已經到達了終點,利用dfs的思想搜索路徑,值得注意的是,我們需要還原狀態,因為可能我們當前走的路徑并不是正確的,所以必須還原到上一個狀態。并且,當我們已經搜索完回路之后,我們需要標記我們已經找到了,避免重新開始而進入死循環。
-
-
代碼
- 拓撲排序
- 并查集處理連通+dfs查找環
第五題 對局匹配
-
問題描述
小明喜歡在一個圍棋網站上找別人在線對弈。這個網站上所有注冊用戶都有一個積分,代表他的圍棋水平。
小明發現網站的自動對局系統在匹配對手時,只會將積分差恰好是K的兩名用戶匹配在一起。
如果兩人分差小于或大于KKK,系統都不會將他們匹配。
現在小明知道這個網站總共有NNN名用戶,以及他們的積分分別是A1,A2,...ANA_1, A_2, ... A_NA1?,A2?,...AN?。
小明想了解最多可能有多少名用戶同時在線尋找對手,但是系統卻一場對局都匹配不起來(任意兩名用戶積分差不等于K)?輸入
第一行包含兩個個整數NNN和KKK。第二行包含NNN個整數A1,A2,...ANA_1, A_2, ... A_NA1?,A2?,...AN?。
對于30%的數據,1<=N<=101 <= N <= 101<=N<=10
對于100%的數據,1<=N<=100000,0<=Ai<=100000,0<=K<=1000001 <= N <= 100000, 0 <= Ai <= 100000, 0 <= K <= 1000001<=N<=100000,0<=Ai<=100000,0<=K<=100000輸出
一個整數,代表答案。
樣例輸入
10 0 1 4 2 8 5 7 1 4 2 8樣例輸出
6 -
解題思路
-
動態規劃
題目所求的即是讓我們盡可能找到多的人使他們任意之間積分之差不等于kkk,我們用cntcntcnt數組來記錄積分的出現次數,那么我們就可以通過這個kkk來分組,然后枚舉i+kj(i∈[0,k?1],j?k<=maxx)i+kj(i\in[0,k-1],j*k<=maxx)i+kj(i∈[0,k?1],j?k<=maxx),這樣,我們就存在著選與不選了,跟背包問題來分析即可。若選擇此時的i+kji+kji+kj,那么就不能繼承上一次的i+k?(j?1)i+k*(j-1)i+k?(j?1)了,而是需要加上i+k?(j?2)i+k*(j-2)i+k?(j?2),而若不選擇,則就是繼承上一次的i+(j?1)ki+(j-1)ki+(j?1)k。最后,累加所有的最終狀態值即可得到答案。
-
貪心+尺取法
我們知道如果兩個人之間積分值相差為k,那么我們隨便取一個出來就可以湊出一個答案了。按照這思想尺取法遍歷所有積分,最后累加即可。
-
-
代碼
- 動態規劃
- 貪心+尺取法
第六題 觀光鐵路
-
問題描述
跳蚤國正在大力發展旅游業,每個城市都被打造成了旅游景點。
許多跳蚤想去其他城市旅游,但是由于跳得比較慢,它們的愿望難以實現。
這時,小C聽說有一種叫做火車的交通工具,在鐵路上跑得很快,便抓住了商機,創立了一家鐵路公司,向跳蚤國王請示在每兩個城市之間都修建鐵路。
然而,由于小C不會扳道岔,火車到一個城市以后只能保證不原路返回,而會隨機等概率地駛向與這個城市有鐵路連接的另外一個城市。
跳蚤國王向廣大居民征求意見,結果跳蚤們不太滿意,因為這樣修建鐵路以后有可能只游覽了3個城市(含出發的城市)以后就回來了,它們希望多游覽幾個城市。
于是跳蚤國王要求小C提供一個方案,使得每只跳蚤坐上火車后能多游覽幾個城市才回來。
小C提供了一種方案給跳蚤國王。跳蚤國王想知道這個方案中每個城市的居民旅游的期望時間(設火車經過每段鐵路的時間都為1),請你來幫跳蚤國王。輸入
輸入的第一行包含兩個正整數n、m,其中n表示城市的數量,m表示方案中的鐵路條數。
接下來m行,每行包含兩個正整數u、v,表示方案中城市u和城市v之間有一條鐵路。
保證方案中無重邊無自環,每兩個城市之間都能經過鐵路直接或間接到達,且火車由任意一條鐵路到任意一個城市以后一定有路可走。
4 <= k <= n <= 21,1 <= u, v <= n輸出
輸出n行,第i行包含一個實數ti,表示方案中城市i的居民旅游的期望時間。
你應當輸出足夠多的小數位數,以保證輸出的值和真實值之間的絕對或相對誤差不超過1e-9。樣例輸入
4 5 1 2 2 3 3 4 4 1 1 3樣例輸出
3.333333333333 5.000000000000 3.333333333333 5.000000000000 -
解題思路
待補。貼出AC代碼供各位參考。
-
代碼
總結
以上是生活随笔為你收集整理的第八届蓝桥杯(软件类)决赛C/C++B组真题题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《人类简史》九、科学革命——承认自己无知
- 下一篇: [c++]平均成绩、从尾到头打印链表、整