文字列を印刷するために必要なダイヤルの回転数を求めるC++コード
すべての小文字の英字アルファベットが刻まれた回転式ダイヤルがあるとします。ダイヤルにはプリンターが取り付けられており、ポインタのある位置の文字が3秒間留まると、その文字が出力(印刷)されます。ダイヤルは初期状態では「a」を指しており、文字を出力した後も初期位置に戻ることはありません。
ここで、文字列 s が与えられるので、この文字列を出力する必要があります。ダイヤルを別の文字へ移動させるたびに、1回分の回転が発生します。与えられた文字列 s を出力するために必要な総回転数を求めてください。
例えば、入力が s = "elephant" の場合、出力は 63 となります。
解法のアプローチ
この問題を解くには、以下の手順に従います。
- 現在のポインタ位置を表す変数
tを「a」で初期化します。 - 答えを格納する変数
resを 0 で初期化します。 - 文字列の各文字について、前の文字から現在の文字への移動に必要な最小回転数を計算して加算します。ダイヤルは円環状になっているため、順方向と逆方向のうち短い方を選びます(
min(|t - s[i]|, 26 - |t - s[i]|))。 - 現在の文字を次の基準位置として更新します。
- すべての文字を処理し終えたら、
resを返します。
t := 'a'
res := 0
for initialize i := 0, when i < size of s, update (increase i by 1),
do:
res := res + minimum of (|t - s[i]|, 26 - |t - s[i]|)
t := s[i]
return res
C++での実装例
理解を深めるために、以下の実装を見てみましょう。
#include <bits/stdc++.h>
using namespace std;
#define N 100
int solve(string s) {
char t = 'a';
int res = 0;
for(int i = 0; i < s.size(); i++){
res += min(abs(t - s[i]), 26 - abs(t - s[i]));
t = s[i];
}
return res;
}
int main() {
string s = "elephant";
cout<< solve(s);
return 0;
}
入力
"elephant"
出力
63
計算の内訳
"elephant" の場合、各文字間の移動に必要な回転数は以下の通りです。
| 移動 | 回転数 |
|---|---|
| a → e | 4 |
| e → l | 7 |
| l → e | 7 |
| e → p | 11 |
| p → h | 8 |
| h → a | 7 |
| a → n | 13 |
| n → t | 6 |
合計:4 + 7 + 7 + 11 + 8 + 7 + 13 + 6 = 63 回転となり、プログラムの出力と一致します。
-
C++で文字列の部分文字列の総数を求める方法を解説
この記事では、与えられた文字列から作成できる空でない部分文字列の個数を求める方法について解説します。入力 : string = "moon" 出力 : 10 説明 : 部分文字列は m、o、o、n、mo、oo、on、moo、oon、moon の 10 個です。 入力 : string = "yellow" 出力 : 21解法のアプローチ文字列の長さを n とします。上の例からも分かるように、考えられるすべての部分文字列の個数を求めるには、長さ n、(n-1)、(n-2)、(n-3)、……2、1 の部分文字列の個数を順に加算していく必要があります。部分文
-
C++で列車の停車駅の組み合わせ数を求める方法
地点XとYの間にはn個の中間駅があるとします。ここで、「どの2つの停車駅も隣り合わない」という条件のもとで、s個の駅に停車する列車の配置方法が何通りあるかを求める問題を考えてみましょう。この記事では、停車駅の組み合わせ数を求めるためのアプローチを段階的に詳しく解説します。この問題は、本質的には組合せ論の問題であり、s個の停車駅の選び方の総数を求めることになります。 問題を解くアプローチ まず具体例として、中間駅が8個あり、そのうち3個の駅に停車させたい場合を考えてみます。 n = 8, s = 3 このとき、列車が停車できない駅は(n − s)、つまり5個残ることになります。 停車できない