ZeroJudge K466: 成績分析 (Analysis)

最近剛考完段考,為了要鼓勵班上同學,老師想要特別頒發禮物給歷次段考中進步最多的學生。另外,老師也想找出退步最多的學生,多加關心學生的學習狀況。

老師會將學生歷次考試較前次考試進步的分數總和記為此學生的進步幅度,而較前次考試退步的分數總和則記為學生的退步幅度。

舉例來說,若一個學生前五次的段考成績分別為 (80、90、60、70、65),他的每筆分數與前次分數的進步分依序為 (10、0、10、0),因此進步幅度為 20。每筆分數與前次分數的退步分依序為 (0、30、0、5),因此退步幅度為 35。

範例測資

範例輸入範例輸出
輸入第一列為兩個整數 N 和 M (3 ≤ N ≤ 1000,2 ≤ M ≤ 100),分別表示學生人數以及考試次數。接下來有 N 列,每一列有 M 個數字 Si (1 ≤ Si ≤ 100,1 ≤ i ≤ M),表示座號 i 的學生歷次考試成績。輸出第一列表示最佳進步的學生座號,第二列表示最需關心的學生座號。
若有多個最佳進步或最需關心的學生則輸出座號最小者
3 5
80 90 60 70 65
70 60 65 60 55
40 50 60 70 80
3
1
3 3
74 44 98
11 75 14
62 19 32
2
2
4 4
33 51 10 76
69 90 69 91
17 55 59 64
46 82 60 26
1
4
8 3
3 83 13
92 45 67
70 19 11
46 78 86
98 61 26
68 78 40
48 94 3
44 9 39
1
7
ZeroJudge K466 範例測資

解題思路

將每個學生的成績存到陣列中,並且邊收資料邊判斷,如果目前收到的資料非數列第一個位置,就判斷收到的資料是比前面的資料大還是小,並且宣告兩個變數 up 和 down 預設為 0,如果是進步就將進步的幅度加到 up,反之將退步的幅度加到 down。

判斷完一個學生所有成績之後要判斷其進步與退步幅度是否為全班最大,因為可能會有進/退步幅度相同的情況,所以判斷的時候要使用 >,當有相同幅度的情況下就會採用較前面也就是學號較小的學生。

範例程式碼-ZeroJudge K466: 成績分析 (Analysis)

#include <iostream>
#include <vector>
using namespace std;

int main() {
    cin.sync_with_stdio(0);
    cin.tie(0);
    int N, M;
    cin >> N >> M;
    int increase = -1, increase_num = 0, decrease = -1, decrease_num = 0;
    for (int i = 0; i<N; i++) {
        vector<int>num;
        int up = 0, down = 0;
        for (int j = 0; j<M; j++) {
            int tmp;
            cin >> tmp;
            num.push_back(tmp);
            if (j > 0) {
                if (num[j] > num[j-1]) up += num[j] - num[j-1];
                if (num[j] < num[j-1]) down += num[j-1] - num[j];
            }
        }
        if (up > increase) {
            increase = up;
            increase_num = i+1;
        }
        if (down > decrease) {
            decrease = down;
            decrease_num = i+1;
        }
    }
    cout << increase_num << "\n" << decrease_num << "\n";
}

//ZeroJudge K466
//Dr. SeanXD

發佈留言