第十二届蓝桥杯 2021年4月 省赛 第一场 C/C++ B组 题解
本題解為非官方題解,可能存在包括但不限于下列問題
- 答案錯誤
- 時間復雜度太高,無法在規定時間內得出結果
填空題答案速覽
目錄
- 填空題
- A 空間 (5分)
- B 卡片 (5分)
- C 直線 (10分)
- D 貨物擺放 (10分)
- E 路徑 (15分)
- 編程題
- F 時間顯示 (15分)
- G 砝碼稱重 (20分)
- H 楊輝三角形 (20分)
- I 雙向排序 (25分)
- J 括號序列 (25分)
填空題
A 空間 (5分)
問題描述
小藍準備用 256256256 MB 的內存空間開一個數組,數組的每個元素都是 323232 位二進制整數,如果不考慮程序占用的空間和維護內存需要的輔助空間,請問 256256256 MB 的空間可以存儲多少個 323232 位二進制整數?
題解
計算機基礎
注意一字節等于八位
(因為考場電腦是32位系統,用 long long 會有奇奇怪怪的錯誤,而且python代碼更短,所以用python寫了)
答案
67108864B 卡片 (5分)
問題描述
小藍有很多數字卡片,每張卡片上都是數字 000 到 999。
小藍準備用這些卡片來拼一些數,他想從 111 開始拼出正整數,每拼一個,就保存起來,卡片就不能用來拼其它數了。
小藍想知道自己能從 111 拼到多少。
例如,當小藍有 303030 張卡片,其中 000 到 999 各 333 張,則小藍可以拼出 111 到 101010,但是拼 111111 時卡片 111 已經只有一張了,不夠拼出 111111。
現在小藍手里有 000 到 999 的卡片各 202120212021 張,共 202102021020210 張,請問小藍可以從 111 拼到多少?
提示:建議使用計算機編程解決問題。
題解
模擬
答案
3181C 直線 (10分)
問題描述
在平面直角坐標系中,兩點可以確定一條直線。如果有多點在一條直線上,那么這些點中任意兩點確定的直線是同一條。
給定平面上 2×32 \times 32×3 個整點 {(x,y)∣0≤x<2,0≤y<3,x∈Z,y∈Z}\{(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z\}{(x,y)∣0≤x<2,0≤y<3,x∈Z,y∈Z},即橫坐標是 000 到 111 (包含 000 和 111) 之間的整數、縱坐標是 000 到 222 (包含 000 和 222) 之間的整數的點。這些點一共確定了 111111 條不同的直線。
給定平面上 20×2120 \times 2120×21 個整點 {(x,y)∣0≤x<20,0≤y<21,x∈Z,y∈Z}\{(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z\}{(x,y)∣0≤x<20,0≤y<21,x∈Z,y∈Z},即橫坐標是 000 到 191919 (包含 000 和 191919) 之間的整數、縱坐標是 000 到 202020 (包含 000 和 202020) 之間的整數的點。請問這些點一共確定了多少條不同的直線。
題解
計算幾何?
解法一
點兩兩連線,算出 k,bk, bk,b 放進set里
(豎直和水平線另算,避免 kkk 為 000 或 ∞\infty∞)
解法二
用 Ax+By+C=0Ax + By + C = 0Ax+By+C=0
其中 A=y1?y2,B=x2?x1,C=x1y2?x2y1A=y_1-y_2, B=x_2-x_1, C=x_1y_2-x_2y_1A=y1??y2?,B=x2??x1?,C=x1?y2??x2?y1?
可以避免浮點運算導致的精度問題
注意 直線 Ax+By+C=0Ax + By + C = 0Ax+By+C=0 與 直線 kAx+kBy+kC=0kAx + kBy + kC = 0kAx+kBy+kC=0 (k∈Z,k≠0)(k∈ Z, k \neq 0)(k∈Z,k?=0) 相同,記錄時需要對 A、B、CA、B、CA、B、C 進行化簡
代碼略
答案
40257D 貨物擺放 (10分)
問題描述
小藍有一個超大的倉庫,可以擺放很多貨物。
現在,小藍有 nnn 箱貨物要擺放在倉庫,每箱貨物都是規則的正方體。小藍規定了長、寬、高三個互相垂直的方向,每箱貨物的邊都必須嚴格平行于長、寬、高。
小藍希望所有的貨物最終擺成一個大的立方體。即在長、寬、高的方向上分別堆 L、W、HL、W、HL、W、H 的貨物,滿足 n=L×W×Hn = L \times W \times Hn=L×W×H。
給定 nnn,請問有多少種堆放貨物的方案滿足要求。
例如,當 n=4n = 4n=4 時,有以下 666 種方案:1×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×11\times1\times4、1\times2\times2、1\times4\times1、2\times1\times2、2\times2\times1、4\times1\times11×1×4、1×2×2、1×4×1、2×1×2、2×2×1、4×1×1。
請問,當 n=2021041820210418n = 2021041820210418n=2021041820210418 (注意有 161616 位數字)時,總共有多少種方案?
提示:建議使用計算機編程解決問題。
題解
數論
對 nnn 分解質因數
2021041820210418=2×3×3×3×17×131×2857×58823532021041820210418 = 2 \times 3 \times 3 \times 3 \times 17 \times 131 \times 2857 \times 58823532021041820210418=2×3×3×3×17×131×2857×5882353
解法一
dfs 算方案放進 set 里
解法二
排列組合
注意到有 333 個 333
35×(1+2+2+2+3)=24303 ^ 5 \times (1+2+2+2+3)=243035×(1+2+2+2+3)=2430
答案
2430E 路徑 (15分)
問題描述
小藍學習了最短路徑之后特別高興,他定義了一個特別的圖,希望找到圖中的最短路徑。
小藍的圖由 202120212021 個結點組成,依次編號 111 至 202120212021。
對于兩個不同的結點 a,ba, ba,b,如果 aaa 和 bbb 的差的絕對值大于 212121,則兩個結點之間沒有邊相連;如果 aaa 和 bbb 的差的絕對值小于等于 212121,則兩個點之間有一條長度為 aaa 和 bbb 的最小公倍數的無向邊相連。
例如:結點 111 和結點 232323 之間沒有邊相連;結點 333 和結點 242424 之間有一條無向邊,長度為 242424;結點 151515 和結點 252525 之間有一條無向邊,長度為 757575。
請計算,結點 111 和結點 202120212021 之間的最短路徑長度是多少。
提示:建議使用計算機編程解決問題。
題解
圖論
解法一
根據題意建邊,跑最短路, Dijkstra 即可
解法二
用 Floyd 跑最短路
雖然時間復雜度為 O(n3)O(n^3)O(n3) ,但是代碼比 Dijkstra 短得多啊!
有寫 Dijkstra 的時間 Floyd 早就跑完了
代碼略
答案
10266837編程題
以下題目時間限制均為 1.0s,內存限制均為 256.0MB
F 時間顯示 (15分)
問題描述
小藍要和朋友合作開發一個時間顯示的網站。在服務器上,朋友已經獲取了當前的時間,用一個整數表示,值為從 197019701970 年 111 月 111 日 00:00:0000:00:0000:00:00 到當前時刻經過的毫秒數。
現在,小藍要在客戶端顯示出這個時間。小藍不用顯示出年月日,只需要顯示出時分秒即可,毫秒也不用顯示,直接舍去即可。
給定一個用整數表示的時間,請將這個時間對應的時分秒輸出。
輸入格式
輸入一行包含一個整數,表示時間。
輸出格式
輸出時分秒表示的當前時間,格式形如 HH:MM:SSHH:MM:SSHH:MM:SS,其中 HHHHHH 表示時,值為 000 到 232323,MMMMMM 表示分,值為 000 到 595959,SSSSSS 表示秒,值為 000 到 595959。時、分、秒不足兩位時補前導 000。
樣例輸入 1
46800999樣例輸出 1
13:00:00樣例輸入 2
1618708103123樣例輸出 2
01:08:23評測用例規模與約定
對于所有評測用例,給定的時間為不超過 101810^{18}1018 的正整數。
題解
模擬
注意 111 秒 =1000=1000=1000 毫秒
#include <bits/stdc++.h> #define ll long long using namespace std; ll n; ll hh, mm, ss; int main() {scanf("%lld", &n);n /= 1000;ss = n % 60;n /= 60;mm = n % 60;n /= 60;hh = n % 24;printf("%02lld:%02lld:%02lld\n", hh, mm, ss);return 0; }G 砝碼稱重 (20分)
問題描述
你有一架天平和 NNN 個砝碼,這 NNN 個砝碼重量依次是 W1,W2,?,WNW_1, W_2,\cdots, W_NW1?,W2?,?,WN?。請你計算一共可以稱出多少種不同的重量?
注意砝碼可以放在天平兩邊。
輸入格式
輸入的第一行包含一個整數 NNN。
第二行包含 NNN 個整數:W1,W2,W3,?,WNW_1, W_2, W_3,\cdots, W_NW1?,W2?,W3?,?,WN?。
輸出格式
輸出一個整數代表答案。
樣例輸入
3 1 4 6樣例輸出
10樣例說明
能稱出的 101010 種重量是:1、2、3、4、5、6、7、9、10、111、2、3、4、5、6、7、9、10、111、2、3、4、5、6、7、9、10、11。
1=11 = 11=1;
2=6?42 = 6 ? 42=6?4 (天平一邊放 666,另一邊放 444);
3=4?13 = 4 ? 13=4?1;
4=44 = 44=4;
5=6?15 = 6 ? 15=6?1;
6=66 = 66=6;
7=1+67 = 1 + 67=1+6;
9=4+6?19 = 4 + 6 ? 19=4+6?1;
10=4+610 = 4 + 610=4+6;
11=1+4+611 = 1 + 4 + 611=1+4+6。
評測用例規模與約定
對于 50%50\%50% 的評測用例,1≤N≤151 \leq N \leq 151≤N≤15。
對于所有評測用例,1≤N≤1001 \leq N \leq 1001≤N≤100,NNN 個砝碼總重不超過 100000100000100000。
題解
dp
解法一 (可能會超時)
對于砝碼 iii ,在使用砝碼 111 到砝碼 i?1i-1i?1 能稱出的重量的基礎上,可以選擇將其放在天平左邊或者右邊
規定砝碼放在左邊為正,放在右邊為負
用 set 記錄所有能稱出的重量
最后再取絕對值去重
注意 000 不算
解法二
dp[i][j]dp[i][j]dp[i][j] 表示前 iii 個物品,若能稱出重量 jjj 則為 111 ,反之為 000
對于 jjj 為負數的情況可以對初始重量 000 進行偏移
因為砝碼總重不超過 100000100000100000 ,偏移量 200000200000200000 即可
狀態轉移方程如下
dp[i][j]={dp[i][j]∣∣dp[i?1][j]不放砝碼?idp[i][j]∣∣dp[i?1][j?wi]砝碼?i放左邊dp[i][j]∣∣dp[i?1][j+wi]砝碼?i放右邊dp[i][j] = \begin{cases} dp[i][j] \ || \ dp[i-1][j]& \text{不放砝碼 $i$ }\\ dp[i][j] \ || \ dp[i-1][j-w_i]& \text{砝碼 $i$ 放左邊}\\ dp[i][j] \ || \ dp[i-1][j+w_i]& \text{砝碼 $i$ 放右邊} \end{cases} dp[i][j]=??????dp[i][j]?∣∣?dp[i?1][j]dp[i][j]?∣∣?dp[i?1][j?wi?]dp[i][j]?∣∣?dp[i?1][j+wi?]?不放砝碼?i?砝碼?i?放左邊砝碼?i?放右邊?
其中 || 為 或運算
H 楊輝三角形 (20分)
問題描述
下面的圖形是著名的楊輝三角形:
如果我們按從上到下、從左到右的順序把所有數排成一列,可以得到如下數列:
1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,?1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1,\cdots1,1,1,1,2,1,1,3,3,1,1,4,6,4,1,?
給定一個正整數 NNN,請你輸出數列中第一次出現 NNN 是在第幾個數?
輸入格式
輸入一個整數 NNN。
輸出格式
輸出一個整數代表答案。
樣例輸入
6樣例輸出
13評測用例規模與約定
對于 20%20\%20% 的評測用例,1≤N≤101 \leq N \leq 101≤N≤10;
對于所有評測用例,1≤N≤10000000001 \leq N \leq 10000000001≤N≤1000000000。
題解
注意到有 n=Cn1n = C_n^1n=Cn1? ,即 nnn 必然會出現在 第 n+1n+1n+1 行 第 222 列 的位置上
若不存在 n=Cij,j≤in = C_i^j , j \leq in=Cij?,j≤i 且 n<Cp2,i≤p<nn < C_p^2, i \leq p<nn<Cp2?,i≤p<n ,則 nnn 只可能在 Cn1C_n^1Cn1? 的位置
即前 p+1p+1p+1 行沒有出現 nnn 且第 p+1p+1p+1 行第三列大于 nnn 的時候就可以直接判斷 nnn 第一次出現在第 n+1n+1n+1 行 第 222 列
暴力枚舉前 p+1p+1p+1 行 (每行的前一半就行了)
最壞情況下 ppp 需要枚舉到 447224472244722 ( C447222=1,000,006,281C_{44722}^2 = 1,000,006,281C447222?=1,000,006,281 )
I 雙向排序 (25分)
問題描述
給定序列 (a1,a2,?,an)=(1,2,?,n)(a_1, a_2,\cdots, a_n) = (1, 2,\cdots, n)(a1?,a2?,?,an?)=(1,2,?,n),即 ai=ia_i = iai?=i。
小藍將對這個序列進行 mmm 次操作,每次可能是將 a1,a2,?,aqia_1, a_2,\cdots, a_{q_i}a1?,a2?,?,aqi?? 降序排列,或者將 aqi,aqi+1,?,ana_{q_i}, a_{q_{i+1}},\cdots, a_naqi??,aqi+1??,?,an? 升序排列。
請求出操作完成后的序列。
輸入格式
輸入的第一行包含兩個整數 n,mn, mn,m,分別表示序列的長度和操作次數。接下來 mmm 行描述對序列的操作,其中第 iii 行包含兩個整數 pip_ipi?, qiq_iqi? 表示操作類型和參數。當 pi=0p_i = 0pi?=0 時,表示將 a1,a2,?,aqia_1, a_2,\cdots, a_{q_i}a1?,a2?,?,aqi?? 降序排列;當 pi=1p_i = 1pi?=1 時,表示將 aqi,aqi+1,?,ana_{q_i}, a_{q_{i+1}},\cdots, a_naqi??,aqi+1??,?,an? 升序排列。
輸出格式
輸出一行,包含 nnn 個整數,相鄰的整數之間使用一個空格分隔,表示操作完成后的序列。
樣例輸入
3 3 0 3 1 2 0 2樣例輸出
3 1 2樣例說明
原數列為 (1,2,3)(1, 2, 3)(1,2,3)。
第 111 步后為 (3,2,1)(3, 2, 1)(3,2,1)。
第 222 步后為 (3,1,2)(3, 1, 2)(3,1,2)。
第 333 步后為 (3,1,2)(3, 1, 2)(3,1,2)。與第 222 步操作后相同,因為前兩個數已經是降序了。
評測用例規模與約定
對于 30%30\%30% 的評測用例,n,m≤1000n, m \leq 1000n,m≤1000;
對于 60%60\%60% 的評測用例,n,m≤5000n, m \leq 5000n,m≤5000;
對于所有評測用例,1≤n,m≤100000,0≤pi≤1,1≤qi≤n1 \leq n, m \leq 100000,0 \leq p_i \leq 1,1 \leq q_i \leq n1≤n,m≤100000,0≤pi?≤1,1≤qi?≤n。
題解
暴力 sort ,時間復雜度 O(mnlog?n)O(mn \log n)O(mnlogn) ,拿 30%30\%30% ~ 60%60\%60% 分
正解暫無
#include <bits/stdc++.h> #define N 100005 using namespace std; int n, m; int a[N], p[N], q[N]; int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) {a[i] = i;}for (int i = 1; i <= m; ++i) {scanf("%d%d", &p[i], &q[i]);if (p[i]) {sort(a + q[i], a + n + 1);} else {sort(a + 1, a + q[i] + 1, greater<int>());}}for (int i = 1; i <= n; ++i) {printf(" %d" + !(i - 1), a[i]);}printf("\n");return 0; }J 括號序列 (25分)
問題描述
給定一個括號序列,要求盡可能少地添加若干括號使得括號序列變得合法,當添加完成后,會產生不同的添加結果,請問有多少種本質不同的添加結果。兩個結果是本質不同的是指存在某個位置一個結果是左括號,而另一個是右括號。
例如,對于括號序列 ((()((()(((),只需要添加兩個括號就能讓其合法,有以下幾種不同的添加結果:()()()()()()()()()、()(())()(())()(())、(())()(())()(())()、(()())(()())(()()) 和 ((()))((()))((()))。
輸入格式
輸入一行包含一個字符串 sss,表示給定的括號序列,序列中只有左括號和右括號。
輸出格式
輸出一個整數表示答案,答案可能很大,請輸出答案除以 100000000710000000071000000007 (即109+710^9 + 7109+7) 的余數。
樣例輸入
((()樣例輸出
5評測用例規模與約定
對于 40%40\%40% 的評測用例,∣s∣≤200\lvert s \rvert \leq 200∣s∣≤200。
對于所有評測用例,1≤∣s∣≤50001 \leq \lvert s \rvert \leq 50001≤∣s∣≤5000。
題解
特判合法括號序列輸出 000
特判樣例騙分
正解暫無
#include <bits/stdc++.h> using namespace std; string s; int cnt; bool flag = true; int main() {cin >> s;for (int i = 0; i < s.length(); ++i) {if (s[i] == '(') {++cnt;} else {if (cnt <= 0) {flag = false;break;}--cnt;}}if (cnt) {flag = false;}if (flag) {printf("0\n");} else {if (s == "((()") {printf("5\n");} else {printf("%d\n", s.length());}}return 0; }總結
以上是生活随笔為你收集整理的第十二届蓝桥杯 2021年4月 省赛 第一场 C/C++ B组 题解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: for循环小技巧,遍历数组的时候要使用恰
- 下一篇: java计算机毕业设计基于安卓Andro