#include <iostream>
#define NUM_STUDENTS 5
#define NUM_SUBJECTS 3
#define STR_LENGTH 30
using namespace::std;

int point[NUM_STUDENTS][NUM_SUBJECTS];

char name[NUM_STUDENTS][STR_LENGTH] =
{
    "畠山　永基",
    "石崎　悠里",
    "緒方　十四夫",
    "丹羽　茂也",
    "米田　由治"
};
char kamoku[NUM_SUBJECTS][STR_LENGTH] =
{
    "国語",
    "数学",
    "英語"
};

class SEISEKI
{
public:
    // ・成績をキーボードから入力する機能
    void point_input()
    {
        for (int i = 0; i < NUM_STUDENTS; ++i)
        {
            cout << name[i] << endl;
            for (int j = 0; j < NUM_SUBJECTS; ++j)
            {
                cout << kamoku[j] << ":";
                cin >> point[i][j];
            }
        }
    }
    // ・成績をモニターで確認する出力機能
    void display()
    {
        for (int i = 0; i < NUM_STUDENTS; ++i)
        {
            cout << name[i] << endl;
            for (int j = 0; j < NUM_SUBJECTS; ++j)
            {
                cout << kamoku[j] << " = " << point[i][j] << '\t';
            }
            cout << endl;
        }
    }
};

class SYUKEI: SEISEKI
{
public:
    // ・各個人別総合展を求める機能
    int get_kojin_sum(int n)
    {
        int sum = 0;
        for (int i = 0; i < NUM_SUBJECTS; ++i)
            sum += point[n][i];
        return sum;
    }

    // ・科目別の平均点を求める機能
    int get_kamoku_avg(int n)
    {
        int sum = 0;
        for (int i = 0; i < NUM_STUDENTS; ++i)
            sum += point[n][i];
        return sum / NUM_STUDENTS;
    }

    // ・各個人別の総合点を画面に表示する機能
    void display_kojin_sum()
    {
        for (int i = 0; i < NUM_STUDENTS; ++i)
            cout << name[i] << '\t' << get_kojin_sum(i) << endl;
    }

    // ・各科目別の平均点を画面に表示する機能
    void display_kamoku_avg()
    {
        for (int i = 0; i < NUM_SUBJECTS; ++i)
            cout << kamoku[i] << '\t' << get_kamoku_avg(i) << endl;
    }
};

int main()
{
    SEISEKI s;
    SYUKEI syu;

    int test_date[] = {23, 45, 67, 89, 12, 34, 56, 78, 90, 12, 34, 56, 78, 90, 12};

    {
        // ・成績をキーボードから入力する場合
        // cout << "\n成績をキーボードから入力する\n";
        // s.point_input();

        // ・成績をプログラムソースから読み込む場合
        {
            int k = 0;
            for (int i = 0; i < NUM_STUDENTS; ++i)
                for (int j = 0; j < NUM_SUBJECTS; ++j)
                    point[i][j] = test_date[k++];
        }

        // 登録データをファイルから読み込む場合
        // {
        //     FILE *fp = fopen("c168-384.cpp.in", "r");
        //     for (int i = 0; i < NUM_STUDENTS; ++i)
        //         for (int j = 0; j < NUM_SUBJECTS; ++j)
        //             fscanf(fp, "%d", &point[i][j]);
        //     fclose(fp);
        // }
    }

    // ・成績をモニターで確認する
    cout << "\n成績をモニターで確認する\n";
    s.display();

    // ・各個人別の総合点を画面に表示する
    cout << "\n各個人別の総合点を画面に表示する\n";
    syu.display_kojin_sum();

    // ・各科目別の平均点を画面に表示する
    cout << "\n各科目別の平均点を画面に表示する\n";
    syu.display_kamoku_avg();

    // ・各科目の最高点を取った人の名前をそれぞれ表示する
    {
        cout << "\n各科目の最高点を取った人の名前をそれぞれ表示する\n";
        for (int j = 0; j < NUM_SUBJECTS; ++j)
        {
            int imax = 0; // 初期値として、最高点は0番目の学生と仮置きする
            for (int i = 0; i < NUM_STUDENTS; ++i)
                if (point[i][j] > point[imax][j])
                    imax = i;
            cout << kamoku[j] << '\t' << name[imax] << endl;
        }
    }

    // ・総合点で最高点を取った人の名前を表示する
    {
        cout << "\n総合点で最高点を取った人の名前を表示する\n";
        int sum[NUM_STUDENTS];
        // 各人の総合点を求める
        for (int i = 0; i < NUM_STUDENTS; ++i)
            sum[i] = syu.get_kojin_sum(i);
        int imax = 0;
        // 総合点の最高を求める
        for (int i = 0; i < NUM_STUDENTS; ++i)
            if (sum[i] > sum[imax])
                imax = i;
        // 最高点に等しい者の名前を表示する（最高点が2人以上の場合も有り得るため）
        for (int i = 0; i < NUM_STUDENTS; ++i)
            if (sum[i] == sum[imax])
                cout << name[i] << endl;
    }
}
