C++で特定の基数におけるパンデジタル数を判定する方法
ある基数Bにおいて、0から基数Bまでのすべての数字を含む数は、その基数における「パンデジタル数」と呼ばれます。ただし、0を含まず1から9までの数字だけで構成される数は、「ゼロなしパンデジタル数」と呼ばれます。パンデジタル数の例としては、0123456789 や 0789564312 などが挙げられます。
問題の概要
このチュートリアルでは、数値と基数が与えられたとき、その数値が指定された基数においてパンデジタル数であるかどうかを判定する問題を取り上げます。以下に入力例と出力例を示します。
入力: num = "9651723467380AZ", base = 10 出力: YES 説明: numには10進法で使用される0から9までのすべての数字が含まれているため、パンデジタル数です。 入力: num = "130264ABCDE745789", base = 16 出力: NO 説明: numには16進法で必要なF(15)が含まれていないため、パンデジタル数ではありません。
解決のためのアプローチ
この問題を解くには、重複しない値だけを保存できるセット(Set)を使用して各桁の値を格納していきます。手順は以下の通りです。
文字列を先頭から順に走査し、1文字ずつ処理します。
その文字が数字(整数)か英字かを判定します。
英字の場合は、アルファベット上の位置に10を加算し、2桁以上の値として表現します。
求めた値をセットに格納します。
走査が完了したら、セットのサイズが基数と一致しているかどうかを確認します。
実装例
上記アプローチのC++コード
#include<bits/stdc++.h>
using namespace std;
int main(){
int base = 10;
char n[] = "9651723467380AZ";
// 重複しない値を格納するためのセットを宣言
set<int, greater<int> > s;
// 文字列を走査
for (int i = 0; i < strlen(n); i++){
// 数字かどうかをチェック
if (n[i] >= '0' && n[i] <= '9')
s.insert(n[i]- '0');
// 英字かどうかをチェック
else if (n[i] - 'A' <= base - 11)
s.insert(n[i] - 'A' + 10);
}
// すべての数字が揃っているか確認
if(s.size()==base)
cout<< "YES";
else
cout<< "NO";
return 0;
}
出力結果
YES
まとめ
このチュートリアルでは、数値と基数が与えられたときに、その数値がパンデジタル数であるかどうかを判定する問題について解説しました。セットに各桁の値を挿入し、最終的なセットのサイズと基数を比較するというシンプルなアプローチを採用しました。ここで示したのはC++による実装ですが、同じロジックはC、Java、Pythonなどの他のプログラミング言語でも容易に実装できます。本チュートリアルが皆様の学習のお役に立てば幸いです。
-
C++で数値内の連続する重複桁を削除する方法
この記事では、数値 n が与えられたとき、その中に含まれる連続する重複桁を削除する方法を解説します。入力: x = 12224 出力: 124 入力: x = 124422 出力: 1242 入力: x = 11332 出力: 132ご覧のとおり、隣り合って繰り返されている桁だけが削除され、離れた位置にある同じ数字はそのまま残ります。この問題では、数値のすべての桁を走査しながら、重複している桁を取り除いていきます。解決のためのアプローチこのアプローチでは、n の各桁を右から左へ順番に調べていきます。具体的には、n を 10 で割った余り(n % 10)で最下位の桁を取り出し、その後 n を
-
C++で五胞体数(ペンタトープ数)を求める方法
五胞体数とは? 五胞体数(ペンタトープ数)は、パスカルの三角形の第5の対角線上に現れる数列として知られています。この数列を定義するには、パスカルの三角形に少なくとも5つの数が必要となるため、数列の最初の数はパスカルの三角形の第4行である 1 4 6 4 1 から始まります。 本チュートリアルでは、n番目の五胞体数を求める方法を解説します。まずは具体的な例を見てみましょう。 入力 : 1出力 : 1入力 : 4出力 : 35 以下の図から出力を確認できます。 この問題は数列に関するものなので、解法ではまず数列のパターンを見つけることから始めます。 解法のアプローチ このプログラムでは、数列の