chenchen題解:CSP-J2019第二次錯題整理
下面是關於CSP-J2019的第二次錯題整理:
解釋:挨個試,對於每一個數x從二開始試,直到根號x
-
#include<cstdio> using namespace std; int n, m; int a[100], b[100]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) a[i] = b[i] = 0; for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); if (a[x] < y && b[y] < x) { if (a[x] > 0) b[a[x]] = 0; if (b[y] > 0) a[b[y]] = 0; a[x] = y; b[y] = x; } } int ans = 0; for (int i = 1; i <= n; ++i) { if (a[i] == 0) ++ans; if (b[i] == 0) ++ans; } printf("%d", ans); return 0; } ```
解釋:
-
#include <iostream> using namespace std; const int maxn = 10000; int n; int a[maxn]; int b[maxn]; int f(int l, int r, int depth) { if (l > r) return 0; int min = maxn, mink; for (int i = l; i <= r; ++i) { if (min > a[i]) { min = a[i]; mink = i; } } int lres = f(l, mink - 1, depth + 1); int rres = f(mink + 1, r, depth + 1); return lres + rres + depth * b[mink]; } int main() { cin >> n; for (int i = 0; i < n; ++i) cin >> a[i]; for (int i = 0; i < n; ++i) cin >> b[i]; cout << f(0, n - 1, 1) << endl; return 0; } ```
解釋(1):
f()
中返回lres + rres + depth * b[mink]
,如果b[]
全為0
,結果一定為0
。
解釋(2):
已知b[0] = 1, b[1] = 2, ..., b[9] = 10
,要輸出最大值,即depth * b[mink]
的和最大,那麼depth
的值應該儘可能的大。與上道題類似,陣列a[]
中元素是有序的,才能保證歸深度最大,最大值= 1 × 1 + 2 × 2 + 3 × 3 + . . . + 10 × 10 = 385
-
(計數排序)計數排序是一個廣泛使用的排序方法。下面的程式使用雙關鍵字計數排序,對 n 對 10000 以內的整數,從小到大排序。
例如有三對整數(3,4)、(2,4)、(3,3),那麼排序之後應該是(2,4)、(3,3)、(3,4)。
輸入第一行為 nn,接下來 nn 行,第 ii 行有兩個數 a[i] 和 b[i],分別表示第 ii 對整數的第一關鍵字和第二關鍵字。
提示:應先對第二關鍵字排序,再對第一關鍵字排序。陣列 ord_____ 儲存第二關鍵字排序的結果,陣列 res_____
儲存雙關鍵字排序的結果。試補全程式
-
#include <cstdio> #include <cstring> using namespace std; const int maxn = 10000000; const int maxs = 10000; int n; unsigned a[maxn], b[maxn],res[maxn], ord[maxn]; unsigned cnt[maxs + 1]; int main() { scanf("%d", &n); for (int i = 0; i < n; ++i) scanf("%d%d", &a[i], &b[i]); memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; ++i) ①; // 利用 cnt 陣列統計數量 for (int i = 0; i < maxs; ++i) cnt[i + 1] += cnt[i]; for (int i = 0; i < n; ++i) ②; // 記錄初步排序結果 memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; ++i) ③; // 利用 cnt 陣列統計數量 for (int i = 0; i < maxs; ++i) cnt[i + 1] += cnt[i]; for (int i = n - 1; i >= 0; --i) ④ // 記錄最終排序結果 for (int i = 0; i < n; i++) printf("%d %d", ⑤); return 0; }
解釋:
計數排序,通過統計每個待排序元素的出現次數,實現排序。本題中,cnt[]
陣列分別統計了兩個關鍵字陣列中每個元素的出現次數,同時又進一步處理了在區間 (0,10000)
中,前i個數中小於等於i的關鍵字個數,可以計算每個關鍵字的排名。
陣列 ord[]
和陣列 res[]
都是以排名為下標,記錄關鍵字在陣列中的位置。陣列 ord[]
儲存第二關鍵字排序的結果,ord[i] = j
表示排名為i
的第二個關鍵字在陣列b[j]
中。陣列 res[]
儲存雙關鍵字排序的結果,res[i] = j
表示最終排名為i的關鍵字在陣列a[j]、b[j]
中。
空①,題目中提示先對第二個關鍵字排序,所以次空應填:cnt[b[i]]++
,記錄所有第二個關鍵字的出現次數。
空②,記錄初步排序結果。通過上面程式碼cnt[i + 1] += cnt[i]
;,cnt[i]
儲存了小於等於i的第二關鍵字的個數,那麼cnt[b[i]
即表示小於等於關鍵字b[i]
的關鍵字個數,即b[i]
的排名。題目中提示ord[]
儲存第二關鍵字排序的結果,此處應將處理結果儲存到陣列ord[]
中,即ord[--cnt[b[i]]] = i
。--cnt[b[i]
保證了排名從0~n-1
,同時,b[i]的出現次數減少一次。
空③,利用 cnt
陣列統計第一個關鍵字的數量,所以次空應填:cnt[a[i]]++
。
空④,通過上面程式碼cnt[i + 1] += cnt[i];
,cnt[i]
儲存了小於等於i
的第一關鍵字的個數,cnt[a[i]]
即表示小於等於關鍵字a[i]的關鍵字個數,即a[i]
的排名。cnt[a[ord[i]]]
表示排名為i的第二關鍵字在陣列位置ord[i]
,其對應的雙關鍵字的排名為cnt[a[ord[i]]],
它所在陣列的位置為ord[i]
。所以此空應填:res[--cnt[a[ord[i]]]] = ord[i]
。
空⑤,陣列 res[] 儲存雙關鍵字排序的結果,所以次空應填:a[res[i]], b[res[i]]
。
相關文章
- 16.C語言錯題整理C語言
- go語言錯題及答案整理Go
- CISSP錯題或模糊知識(未整理)
- 用指令碼整理Leetcode題解指令碼LeetCode
- Luogu P5663 CSP-J2019 加工零件 題解 [ 綠 ] [ 同餘最短路 ]
- 【問題】Nacos 使用問題整理
- Docker問題整理Docker
- 題目整理01
- 面試題整理面試題
- 複試題整理
- LeetCode刷題整理LeetCode
- 1.3 OGG問題解決整理(中文亂碼、mysql端語法錯誤、XA事務問題等持續更新)MySql
- 解決 Inkscape 報錯 Duplicate 問題
- CSP歷年複賽題-P5660 [CSP-J2019] 數字遊戲遊戲
- 利用PCT解決快速重新整理效能問題
- Flume面試題整理面試題
- linux面試題整理Linux面試題
- 正則問題整理
- 前端面試題整理前端面試題
- Laravel 面試題整理Laravel面試題
- JavaScript面試題整理JavaScript面試題
- CSS面試題整理CSS面試題
- 執行 NPM run watch-poll 各種報錯問題整理NPM
- 解決 ngrok 的 Domain 錯誤問題AI
- 解決eslint空格報錯等問題EsLint
- VSCode除錯Flutter的問題解決VSCode除錯Flutter
- 「面試題」20+Vue面試題整理面試題Vue
- 錯題本
- C++刷題tricks整理C++
- Spark面試題整理(三)Spark面試題
- Flutter module模式問題整理Flutter模式
- 前端面試題整理--http前端面試題HTTP
- 移動端問題整理
- 【web前端】面題整理(2)Web前端
- <開放世界>專題整理
- 面試題整理—CSS部分面試題CSS
- Java相關問題整理Java
- Java面試題整理《上》Java面試題