考前一天晚上失眠.......(其實主要不是因為考試的原因)
很幸運,我們學校就是一個考點,本場作戰,應該有一點加持吧.
上午在家復習,看到一篇關於PN532模擬小米手環加密卡的文章,於是,,,,,,,,你們懂的,荒廢了.
下午1點過正式出征,在熟悉的學校排了一會,碰到幾個同學,甚至還有小學同學!
2點半開考,先讓我們看了10分鍾卷子,我說這個完善程序第二題怎么這么簡單啊(大霧),結果最后做自閉了....
選擇題出奇簡單,事實證明我全對.而且,一個基礎知識題都沒有!CCF真的是大刀闊斧的改革!
讀程序沒什么可說的,逼瘋眾考生第二題只試了幾組數據就寫出來了,錯了一個判斷.
就是這道:
看樣子是數據試少了(霧*2)
實際上你看看這答案解析不是在試數據是在干嘛!要不然誰搞得懂CCF出的鬼題是什么意思!
閱讀程序第三道的最后一題,簡直跪了,考場上猜了D
實際上我的思路是對的.最好的情況,也就是輸出最小,就是每次都2分.
100 個節點的每層節點數量就是 (1,2,4,8,16,32,37)分別乘對應權值即可 1+4+12+32+80+192+259
但是,我天真的列出來1,2,4,8,16,32,64,算出來600多,呵呵...
完善程序第一道,簡單,全對.
但這個思路清奇,加上位運算的使用,可以學習一下.
最后來說說完善程序第二道,難哭
重了幾層數組,出題人不數數的嗎!!!!!
好了,來說說正解.
我們先拋開雙關鍵字,看看單關鍵字,最普通的基數排序.
找到一篇很好的文章:https://www.itcodemonkey.com/article/11750.html
這里是計數排序算法演示
:
還有網上找的代碼:
#include <iostream> #include <stdio.h> using namespace std; void COUNTINGSORT(int *A,int *B,int len,int k){ if(A == NULL || k <= 0 || len <= 0){ return; } int C[k+1],i; //初始化 for(i = 0;i <= k;i++){ C[i] = 0; } //統計值為A[i]的個數,C[i]是等於i的元素個數 for(i = 0;i < len;i++){ C[A[i]] ++; }
//標記1 //確定值A[i]在最終輸出數組B中位置,C[i]是小於等於i的元素個數 for(i = 1;i <= k;i++){ C[i] += C[i-1]; } //輸出到數組B中 for(i = len-1;i >= 0;i--){ //index元素A[i]在數組B中的下標 int index = C[A[i]]; B[index] = A[i]; //如果有相同值元素的情況 C[A[i]] --; } //B下標從1開始 } int main(){ int A[8] = {2,5,3,0,2,3,0,3}; int B[9]; COUNTINGSORT(A,B,8,5); for(int i = 1;i <= 8;i++){ printf("%d\n",B[i]); } return 0; }
在這個地方,其實相當於把程序的標記1做完了,下面的for循環就是在做前綴和,做完后是:
1 3 6 7 7 9
做了前綴和有什么用呢?看下面代碼:
for(i = len-1;i >= 0;i--){ //index元素A[i]在數組B中的下標 int index = C[A[i]]; B[index] = A[i]; //如果有相同值元素的情況 C[A[i]] --; }
相當於題中的 ord[--cnt[b[i]]] = i
到這里便不難理解了.
最后回到考題雙關鍵字,就是多套了幾個數組,沒什么區別.
自測分數84,等着出成績吧,反正四川慢的很。(心里還有一點小激動呢)
最后 復賽good luck!
附2019CSP-J初賽試題及答案
鏈接: https://pan.baidu.com/s/1FmJHHaYZZSwDC_6J7I8x4A&shfl=shareset 提取碼: u6kv