C++で相対ランクを求める:上位3名に金・銀・銅メダルを割り当てるアルゴリズム
問題概要
N人の選手のスコアのリストが与えられ、それぞれの相対的な順位を求めます。中でも最も高いスコアを持つ上位3名には、それぞれ「Gold(金)」「Silver(銀)」「Bronze(銅)」のメダルを割り当てます。
たとえば、入力が [2,5,3,1,0] の場合、出力は [Bronze, Gold, Silver, 4, 5] となります。
解法のアプローチ
この問題は、以下の手順で解くことができます。
- nums のサイズが 1 の場合は「Gold」を返します。
- nums のサイズが 2 の場合は、nums[0] > nums[1] であれば「Gold, Silver」を、そうでなければ「Silver, Gold」を返します。
- 配列 v と vec を定義します。
- nums のすべての要素を v の末尾に追加します。
- 配列 v をソートし、さらに逆順(降順)に並べ替えます。
- マップ mp を定義します。
- nums のサイズが 2 より大きい場合、次の処理を行います。
- mp に {v[0], Gold}、{v[1], Silver}、{v[2], Bronze} を登録します。
- i = 3 から v の末尾まで、{v[i], 順位(i + 1 の文字列表現)} を mp に登録します。
- nums の各要素 i について、mp[nums[i]] を vec の末尾に追加します。
- vec を返します。
アルゴリズムのポイント
この解法では、元の配列の順序を保持しながら順位を求める必要があるため、まずスコアのコピーを作成して降順にソートし、各スコアと順位(またはメダル名)の対応をマップに記録します。あとは元の配列を先頭から走査し、マップを参照することで、対応する結果を正しい位置に配置できます。全体の計算量は O(N log N) となり、ボトルネックはソート処理です。
実装例
以下のC++実装を見ると、より理解が深まるでしょう。
#include <bits/stdc++.h>
using namespace std;
void print_vector(vector<auto> v){
cout << "[";
for(int i = 0; i<v.size(); i++){
cout << v[i] << ", ";
}
cout << "]"<<endl;
}
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& nums){
if (nums.size() == 1){
return { "Gold" };
}
if (nums.size() == 2){
if (nums[0] > nums[1])
return { "Gold", "Silver" };
else
return { "Silver", "Gold" };
}
vector<int> v;
vector<string> vec;
for (int i = 0; i < nums.size(); i++)
v.push_back(nums[i]);
sort(v.begin(), v.end());
reverse(v.begin(), v.end());
map<int, string> mp;
if (nums.size() > 2) {
mp.insert({v[0], "Gold" });
mp.insert({v[1], "Silver" });
mp.insert({v[2], "Bronze" });
for (int i = 3; i < v.size(); i++) {
mp.insert({ v[i], to_string(i + 1) });
}
for (int i = 0; i < nums.size(); i++)
vec.push_back(mp[nums[i]]);
}
return vec;
}
};
main(){
Solution ob;
vector<int> v = {2,5,3,1,0};
print_vector(ob.findRelativeRanks(v));
}入力
{2,5,3,1,0}出力
[Bronze, Gold, Silver, 4, 5]
-
C++で質素数(Frugal Number)を判定する方法【サンプルコード付き】
この記事では、正の整数 N が与えられたときに、その数が質素数(Frugal Number)であるかどうかを判定するプログラムを C++ で作成する方法を解説します。 質素数とは? 質素数(FRUGAL NUMBER)とは、その数自身の桁数が、素因数分解による表現の桁数よりも厳密に大きい数のことです。 例:625 の場合 625 を素因数分解すると 54 となります。 625 自身の桁数:3 桁 54 の表現の桁数:2 桁 3 は 2 よりも厳密に大きいため、625 は質素数です。 最初のいくつかの質素数:125、128、243、256、343、512、625 など 問題を理解するための具
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の