红包分配システムの実装とソート処理

問題概要

N人の参加者間での紅包(お年玉)の分配記録を処理し、各人の収支を計算するプログラムを作成します。入力データから各人の収入金額、支出金額、獲得紅包数を算出し、指定された条件でソートして出力します。

入力形式

最初の行には参加者数N(≤104)が与えられます。続くN行には、各参加者が発行した紅包の情報が以下の形式で記述されます:

K N1 P1 N2 P2 ... NK PK

ここでKは発行紅包数、Niは紅包獲得者の番号、Piは獲得金額(単位:分)です。同一人物からの紅包は1回のみ獲得可能です。

出力形式

収入金額の降順で各参加者の番号と収入金額(単位:元、小数点以下2桁)を出力します。収入金額が同値の場合は獲得紅包数の降順、さらに同値の場合は参加者番号の昇順でソートします。

データ構造設計

struct Participant {
    int id;           // 参加者ID
    int received;     // 受取金額(分)
    int sent;         // 送金額(分)
    int count;        // 獲得紅包数
    double balance;   // 収支残高(元)
};

Participant participants[10000];

比較関数の実装

bool compareParticipants(const Participant &a, const Participant &b) {
    if (a.balance != b.balance) 
        return a.balance > b.balance;
    if (a.count != b.count) 
        return a.count > b.count;
    return a.id < b.id;
}

処理フロー

初期化処理

int main() {
    int n;
    cin >> n;
    
    // 参加者データの初期化
    for (int i = 0; i < n; i++) {
        participants[i].id = i + 1;
        participants[i].received = 0;
        participants[i].sent = 0;
        participants[i].count = 0;
    }

データ入力と処理

    // 紅包データの読み込みと処理
    for (int i = 0; i < n; i++) {
        int k;
        cin >> k;
        
        for (int j = 0; j < k; j++) {
            int receiver, amount;
            cin >> receiver >> amount;
            
            // 送金額の加算
            participants[i].sent += amount;
            // 受取金額と獲得数の更新
            participants[receiver - 1].received += amount;
            participants[receiver - 1].count++;
        }
    }

収支計算と出力

    // 収支計算
    for (int i = 0; i < n; i++) {
        participants[i].balance = 
            (participants[i].received - participants[i].sent) / 100.0;
    }
    
    // ソート実行
    sort(participants, participants + n, compareParticipants);
    
    // 結果出力
    cout << fixed << setprecision(2);
    for (int i = 0; i < n; i++) {
        cout << participants[i].id << " " << participants[i].balance << endl;
    }
    
    return 0;
}

完全な実装コード

#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;

struct Participant {
    int id;
    int received;
    int sent;
    int count;
    double balance;
};

Participant participants[10000];

bool compareParticipants(const Participant &a, const Participant &b) {
    if (a.balance != b.balance) 
        return a.balance > b.balance;
    if (a.count != b.count) 
        return a.count > b.count;
    return a.id < b.id;
}

int main() {
    int n;
    cin >> n;
    
    for (int i = 0; i < n; i++) {
        participants[i].id = i + 1;
        participants[i].received = 0;
        participants[i].sent = 0;
        participants[i].count = 0;
    }
    
    for (int i = 0; i < n; i++) {
        int k;
        cin >> k;
        
        for (int j = 0; j < k; j++) {
            int receiver, amount;
            cin >> receiver >> amount;
            
            participants[i].sent += amount;
            participants[receiver - 1].received += amount;
            participants[receiver - 1].count++;
        }
    }
    
    for (int i = 0; i < n; i++) {
        participants[i].balance = 
            (participants[i].received - participants[i].sent) / 100.0;
    }
    
    sort(participants, participants + n, compareParticipants);
    
    cout << fixed << setprecision(2);
    for (int i = 0; i < n; i++) {
        cout << participants[i].id << " " << participants[i].balance << endl;
    }
    
    return 0;
}

タグ: アルゴリズム データ構造 C++ ソート 競技プログラミング

7月11日 16:44 投稿