#include <iostream>
#include <vector>
#include <unordered_map>
#include <iomanip>
#include <string>
const long long VOL_PER_DONOR = 450 ;
// Struktur Data Esensial
struct DataDonor { int ID_Desa; char GolonganDarah; } ;
struct HasilGolongan { int Pendonor = 0 ; long long Volume_ml = 0 ; } ;
using HasilDetail = std:: unordered_map < char , HasilGolongan> ;
using SistemDataDDS = std:: unordered_map < int , std:: vector < DataDonor>> ;
// --- FUNGSI INTI SUBPROGRAM ---
void HitungDanTampilkanDDS( int ID_Desa, const SistemDataDDS& DataDDS) {
auto it = DataDDS.find ( ID_Desa) ;
if ( it == DataDDS.end ( ) ) { std:: cout << "Desa ID " << ID_Desa << " tidak ditemukan." << std:: endl ; return ; }
HasilDetail hasil;
// 1. Iterasi & Kelompokkan (O(D) - Cepat)
for ( const auto & donor : it- > second) {
char gol = std:: toupper ( donor.GolonganDarah ) ;
hasil[ gol] .Pendonor ++ ;
}
// 2. Tampilkan Output
std:: cout << "\n --- HASIL DESA ID: " << ID_Desa << " ---" << std:: endl ;
std:: cout << std:: left << std:: setw ( 10 ) << "GOL"
<< std:: setw ( 12 ) << "JUMLAH"
<< "VOLUME (ml)" << std:: endl ;
std:: cout << "--------------------------------" << std:: endl ;
for ( const auto & pair : hasil) {
// Hitung Volume
long long volume = pair.second .Pendonor * VOL_PER_DONOR;
// Format Tampilan ('X' -> 'AB')
std:: string gol_str = ( pair.first == 'X' ) ? "AB" : std:: string ( 1 , pair.first ) ;
std:: cout << std:: left << std:: setw ( 10 ) << gol_str
<< std:: setw ( 12 ) << pair.second .Pendonor
<< volume << std:: endl ;
}
std:: cout << "--------------------------------" << std:: endl ;
}
// --- MAIN DEMONSTRASI ---
int main( ) {
SistemDataDDS data_sistem;
// Simulasi Input Data: Desa 101 dan 202
data_sistem[ 101 ] = { { 101 , 'A' } , { 101 , 'B' } , { 101 , 'A' } , { 101 , 'O' } , { 101 , 'X' } } ; // X=AB
data_sistem[ 202 ] = { { 202 , 'O' } , { 202 , 'O' } , { 202 , 'B' } , { 202 , 'X' } } ;
// Panggil Subprogram
HitungDanTampilkanDDS( 101 , data_sistem) ;
HitungDanTampilkanDDS( 202 , data_sistem) ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPGlvbWFuaXA+CiNpbmNsdWRlIDxzdHJpbmc+Cgpjb25zdCBsb25nIGxvbmcgVk9MX1BFUl9ET05PUiA9IDQ1MDsgCgovLyBTdHJ1a3R1ciBEYXRhIEVzZW5zaWFsCnN0cnVjdCBEYXRhRG9ub3IgeyBpbnQgSURfRGVzYTsgY2hhciBHb2xvbmdhbkRhcmFoOyB9OwpzdHJ1Y3QgSGFzaWxHb2xvbmdhbiB7IGludCBQZW5kb25vciA9IDA7IGxvbmcgbG9uZyBWb2x1bWVfbWwgPSAwOyB9Owp1c2luZyBIYXNpbERldGFpbCA9IHN0ZDo6dW5vcmRlcmVkX21hcDxjaGFyLCBIYXNpbEdvbG9uZ2FuPjsKdXNpbmcgU2lzdGVtRGF0YUREUyA9IHN0ZDo6dW5vcmRlcmVkX21hcDxpbnQsIHN0ZDo6dmVjdG9yPERhdGFEb25vcj4+OwoKLy8gLS0tIEZVTkdTSSBJTlRJIFNVQlBST0dSQU0gLS0tCnZvaWQgSGl0dW5nRGFuVGFtcGlsa2FuRERTKGludCBJRF9EZXNhLCBjb25zdCBTaXN0ZW1EYXRhRERTJiBEYXRhRERTKSB7CiAgICBhdXRvIGl0ID0gRGF0YUREUy5maW5kKElEX0Rlc2EpOwogICAgaWYgKGl0ID09IERhdGFERFMuZW5kKCkpIHsgc3RkOjpjb3V0IDw8ICJEZXNhIElEICIgPDwgSURfRGVzYSA8PCAiIHRpZGFrIGRpdGVtdWthbi4iIDw8IHN0ZDo6ZW5kbDsgcmV0dXJuOyB9CgogICAgSGFzaWxEZXRhaWwgaGFzaWw7CiAgICAKICAgIC8vIDEuIEl0ZXJhc2kgJiBLZWxvbXBva2thbiAoTyhEKSAtIENlcGF0KQogICAgZm9yIChjb25zdCBhdXRvJiBkb25vciA6IGl0LT5zZWNvbmQpIHsKICAgICAgICBjaGFyIGdvbCA9IHN0ZDo6dG91cHBlcihkb25vci5Hb2xvbmdhbkRhcmFoKTsKICAgICAgICBoYXNpbFtnb2xdLlBlbmRvbm9yKys7CiAgICB9CgogICAgLy8gMi4gVGFtcGlsa2FuIE91dHB1dAogICAgc3RkOjpjb3V0IDw8ICJcbi0tLSBIQVNJTCBERVNBIElEOiAiIDw8IElEX0Rlc2EgPDwgIiAtLS0iIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmxlZnQgPDwgc3RkOjpzZXR3KDEwKSA8PCAiR09MIiAKICAgICAgICAgICAgICA8PCBzdGQ6OnNldHcoMTIpIDw8ICJKVU1MQUgiIAogICAgICAgICAgICAgIDw8ICJWT0xVTUUgKG1sKSIgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8ICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIgPDwgc3RkOjplbmRsOwoKICAgIGZvciAoY29uc3QgYXV0byYgcGFpciA6IGhhc2lsKSB7CiAgICAgICAgLy8gSGl0dW5nIFZvbHVtZQogICAgICAgIGxvbmcgbG9uZyB2b2x1bWUgPSBwYWlyLnNlY29uZC5QZW5kb25vciAqIFZPTF9QRVJfRE9OT1I7CiAgICAgICAgCiAgICAgICAgLy8gRm9ybWF0IFRhbXBpbGFuICgnWCcgLT4gJ0FCJykKICAgICAgICBzdGQ6OnN0cmluZyBnb2xfc3RyID0gKHBhaXIuZmlyc3QgPT0gJ1gnKSA/ICJBQiIgOiBzdGQ6OnN0cmluZygxLCBwYWlyLmZpcnN0KTsKCiAgICAgICAgc3RkOjpjb3V0IDw8IHN0ZDo6bGVmdCA8PCBzdGQ6OnNldHcoMTApIDw8IGdvbF9zdHIKICAgICAgICAgICAgICAgICAgPDwgc3RkOjpzZXR3KDEyKSA8PCBwYWlyLnNlY29uZC5QZW5kb25vciAKICAgICAgICAgICAgICAgICAgPDwgdm9sdW1lIDw8IHN0ZDo6ZW5kbDsKICAgIH0KICAgIHN0ZDo6Y291dCA8PCAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iIDw8IHN0ZDo6ZW5kbDsKfQoKLy8gLS0tIE1BSU4gREVNT05TVFJBU0kgLS0tCmludCBtYWluKCkgewogICAgU2lzdGVtRGF0YUREUyBkYXRhX3Npc3RlbTsKCiAgICAvLyBTaW11bGFzaSBJbnB1dCBEYXRhOiBEZXNhIDEwMSBkYW4gMjAyCiAgICBkYXRhX3Npc3RlbVsxMDFdID0ge3sxMDEsICdBJ30sIHsxMDEsICdCJ30sIHsxMDEsICdBJ30sIHsxMDEsICdPJ30sIHsxMDEsICdYJ319OyAvLyBYPUFCCiAgICBkYXRhX3Npc3RlbVsyMDJdID0ge3syMDIsICdPJ30sIHsyMDIsICdPJ30sIHsyMDIsICdCJ30sIHsyMDIsICdYJ319OwoKICAgIC8vIFBhbmdnaWwgU3VicHJvZ3JhbQogICAgSGl0dW5nRGFuVGFtcGlsa2FuRERTKDEwMSwgZGF0YV9zaXN0ZW0pOwogICAgSGl0dW5nRGFuVGFtcGlsa2FuRERTKDIwMiwgZGF0YV9zaXN0ZW0pOwoKICAgIHJldHVybiAwOwp9