【超高效代码】1059 C语言竞赛 (20分)
立志用更少的代碼做更高效的表達
Pat乙級最優化代碼+題解+分析匯總——>傳送門
C 語言競賽是浙江大學計算機學院主持的一個歡樂的競賽。既然競賽主旨是為了好玩,頒獎規則也就制定得很滑稽:
 
 0、冠軍將贏得一份“神秘大獎”(比如很巨大的一本學生研究論文集……)。
 1、排名為素數的學生將贏得最好的獎品 —— 小黃人玩偶!
 2、其他人將得到巧克力。
 給定比賽的最終排名以及一系列參賽者的 ID,你要給出這些參賽者應該獲得的獎品。
輸入格式:
 輸入第一行給出一個正整數 N(≤10^?4 ),是參賽者人數。隨后 N 行給出最終排名,每行按排名順序給出一位參賽者的 ID(4 位數字組成)。接下來給出一個正整數 K 以及 K 個需要查詢的 ID。
輸出格式:
 對每個要查詢的 ID,在一行中輸出 ID: 獎品,其中獎品或者是 Mystery Award(神秘大獎)、或者是 Minion(小黃人)、或者是 Chocolate(巧克力)。如果所查 ID 根本不在排名里,打印 Are you kidding?(耍我呢?)。如果該 ID 已經查過了(即獎品已經領過了),打印 ID: Checked(不能多吃多占)。
輸入樣例:
 6
 1111
 6666
 8888
 1234
 5555
 0001
 6
 8888
 0001
 1111
 2222
 8888
 2222
 輸出樣例:
 8888: Minion
 0001: Chocolate
 1111: Mystery Award
 2222: Are you kidding?
 8888: Checked
 2222: Are you kidding?
解析
如果每輸入一個數,都判斷它是否為素數, 那么時間復雜度會非常高, 而本題又規定了輸入數的范圍(小于1w),因此考慮用篩選法求素數。
這種方法比較好理解:初始時,假設全部都是素數,當找到一個素數時,顯然這個素數乘上另外一個數之后都是合數(i是素數,那么i1,i2…i*n就是合數),把這些合數都篩掉,即算法名字的由來。(這里我用的是非線性篩,雖然效率不如線性曬,但更好理解,對付本題也足夠了~)
求出素數后,進行如下分類:
- 如果是第一個輸入的數,則置為3
 - 如果是素數,則對應的值置為1
 - 如果不是素數,則置為-1
 
接下來進行遍歷,判斷即可。
代碼
#include<bits/stdc++.h> using namespace std; int a[10010] = {0}, b[10010] = {0}; //a數組判斷是否是素數,b數組存放具體值 int main() {a[0] = a[1] = 1;for(int i = 2; i < 10010/2; i++) if(a[i] == 0) for(int j = i*2; j <= 10010; j += i) a[j] = 1; int n; cin>>n;int first;for(int i = 1; i <= n; i++) {int x; cin >> x;if(i == 1) { b[x] = 3; continue; } //代表是冠軍 if(a[i] == 0) b[x] = 1; //如果是素數 else b[x] = -1; //如果不是素數 } cin >> n;for(int i = 0; i < n; i++) {int x; cin >> x;if(b[x] == 3) { //如果是冠軍 printf("%04d: Mystery Award\n",x);b[x] = 2;} else if(b[x] == 1) { //如果是素數 printf("%04d: Minion\n", x);b[x] = 2; } else if(b[x] == -1) { //如果不是素數 printf("%04d: Chocolate\n", x);b[x] = 2;}else if(b[x] == 2) { //如果領過獎printf("%04d: Checked\n", x);} else { //沒有出現過的序號 printf("%04d: Are you kidding?\n", x); }}return 0; }沖沖沖~ PAT加油~
總結
以上是生活随笔為你收集整理的【超高效代码】1059 C语言竞赛 (20分)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 【解析】1057 数零壹 (20分)(进
 - 下一篇: 【测试点分析】1060 爱丁顿数 (25