患者の並び替え問題
患者が診察を受けに来院し、以下のルールに基づいて診察の順番を決定するプログラムを作成する。
- 高齢者(年齢が60歳以上)は、若年者より優先される。
- 高齢者は年齢が高い順に診察され、年齢が同じ場合は来院順に診察される。
- 若年者は来院順に診察される。
解法のポイント
この問題は、カスタム比較ロジックを使用した構造体のソートをテストするものである。患者の情報を構造体で管理し、ソートアルゴリズム(ここでは標準ライブラリのstd::sortを使用)に比較関数を渡すのが効率的な方法である。
実装例(C++)
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
struct Patient {
std::string id;
int age;
int arrivalOrder; // 来院順を記録するためのフィールド
};
// 比較関数
bool comparePatients(const Patient& a, const Patient& b) {
bool isSeniorA = a.age >= 60;
bool isSeniorB = b.age >= 60;
// 高齢者は若年者より優先
if (isSeniorA && !isSeniorB) {
return true;
}
if (!isSeniorA && isSeniorB) {
return false;
}
// 両方とも高齢者の場合、年齢が高い順
if (isSeniorA && isSeniorB) {
if (a.age != b.age) {
return a.age > b.age;
}
// 年齢が同じなら来院順
return a.arrivalOrder < b.arrivalOrder;
}
// 両方とも若年者の場合、来院順
return a.arrivalOrder < b.arrivalOrder;
}
int main() {
int patientCount;
std::cin >> patientCount;
std::vector<Patient> patients(patientCount);
for (int i = 0; i < patientCount; ++i) {
patients[i].id = "P" + std::to_string(i + 1); // IDを生成(例)
std::cin >> patients[i].age;
patients[i].arrivalOrder = i; // 来院順を記録
}
// カスタム比較関数でソート
std::sort(patients.begin(), patients.end(), comparePatients);
// 結果を出力
for (const auto& p : patients) {
std::cout << p.id << " " << p.age << std::endl;
}
return 0;
}
卓球のスコア計算
卓球の試合の各ポイントの勝敗(W:プレイヤーAの勝ち, L:プレイヤーBの勝ち)を記録した文字列が与えられる。この記録に基づき、11点制と21点制のそれぞれの試合結果を計算する。
解法のポイント
複数行の入力を一つの文字列に結合し、文字を一つずつ処理する。プレイヤーAとBのスコアをカウントし、どちらかのスコアが11点(または21点)に達し、かつ得点差が2以上になった時点でセットの結果を出力し、スコアをリセットする。入力の終わり('E')が検出されたら処理を終了する。
実装例(C++)
#include <iostream>
#include <string>
void calculateScore(const std::string& gameRecord, int targetScore) {
int scoreA = 0, scoreB = 0;
for (char c : gameRecord) {
if (c == 'E') break;
if (c == 'W') {
scoreA++;
} else if (c == 'L') {
scoreB++;
}
// セットの終了条件をチェック
if ((scoreA >= targetScore || scoreB >= targetScore) && std::abs(scoreA - scoreB) >= 2) {
std::cout << scoreA << ":" << scoreB << std::endl;
scoreA = 0;
scoreB = 0;
}
}
// 最後のセットの結果を出力
std::cout << scoreA << ":" << scoreB << std::endl;
}
int main() {
std::string fullRecord;
std::string line;
// 入力をすべて結合する
while (std::cin >> line) {
if (line.find('E') != std::string::npos) {
fullRecord += line.substr(0, line.find('E'));
break;
}
fullRecord += line;
}
// 11点制と21点制の結果を計算
std::cout << "11点制の結果:" << std::endl;
calculateScore(fullRecord, 11);
std::cout << std::endl << "21点制の結果:" << std::endl;
calculateScore(fullRecord, 21);
return 0;
}
秘密の部屋の探索
2つのパスコード(10進数、最大63)が与えられる。これらを8ビットの2進数に変換し、ビットごとの論理積(AND)を計算する。結果の2進数の右から数えて、nビット目が1である場合、n番目の秘密の部屋を開けることができる。少なくとも2つの部屋を開けることができれば、大门を開けることができる。
解法のポイント
2つの10進数をビットセット(std::bitset)に変換し、ビット単位のAND演算を実行する。結果のビットセットをスキャンし、'1'のビットの位置(部屋の番号)を特定する。'1'のビットの総数が2以上であれば、大门を開けることができる。
実装例(C++)
#include <iostream>
#include <bitset>
int main() {
int passcode1, passcode2;
std::cin >> passcode1 >> passcode2;
// 8ビットのビットセットに変換
std::bitset<8> binary1(passcode1);
std::bitset<8> binary2(passcode2);
// ビットごとのAND演算
std::bitset<8> result = binary1 & binary2;
int openableRoomCount = 0;
std::cout << "開けることができる部屋の番号: ";
for (int i = 0; i < 8; ++i) {
if (result[i] == 1) {
// ビットの位置(0~7)を部屋の番号(1~8)に変換
std::cout << (i + 1) << " ";
openableRoomCount++;
}
}
std::cout << std::endl;
// 大门を開けることができるか判定
if (openableRoomCount >= 2) {
std::cout << "大门: Open" << std::endl;
} else {
std::cout << "大门: Close" << std::endl;
}
return 0;
}