C++で時針と分針のなす角がθとなる時刻を求める方法
問題の概要
角度θ(シータ)が与えられたとき、時計の時針と分針がちょうどその角度をなす時刻を「hh:mm」形式で求めることを考えます。例えば、角度が90°であれば、答えの一つとして「3:00」が挙げられます。
解き方のアプローチ
時計は12時間表示のため、時は12通り(0〜11)、分は60通り(0〜59)の組み合わせが存在します。つまり、調べるべき時刻は最大でも12×60=720通りです。そこで、すべての時刻の組み合わせを順番に調べ、各時刻における時針と分針のなす角を計算します。その角度が与えられたθと一致した時点で、その時刻を出力します。
角度の計算方法
時針と分針の角度は、それぞれ次の式で求められます。
- 時針の角度 = 0.5 × (時 × 60 + 分) … 時針は12時間で360°回転するため、1分あたり0.5°ずつ進みます。
- 分針の角度 = 6 × 分 … 分針は60分で360°回転するため、1分あたり6°ずつ進みます。
両者の差の絶対値を取った後、360°から引いた値と比較し、小さい方を採用します。これにより、時計回り・反時計回りのうち短い方の角度が得られます。
C++での実装例
#include<iostream>
#include<cmath>
using namespace std;
float angleFromClockHand(int hour, int minute) {
float hour_angle = 0.5 * (hour*60 + minute);
float minute_angle = 6*minute;
float angle = abs(hour_angle - minute_angle);
angle = min(360-angle, angle);
return angle;
}
void findTime(float theta) {
for (int hour=0; hour<12; hour++) {
for (int min=0; min<60; min++) {
if (angleFromClockHand(hour, min)==theta) {
cout << hour << ":"<< min;
return;
}
}
}
cout << "Unable to find time";
}
int main() {
float angle = 45.0;
findTime(angle);
}実行結果
4:30
この例では角度として45.0°を指定しているため、時針と分針が45°をなす最初の時刻として「4:30」が出力されます。4時30分の時点では、時針は0.5×(4×60+30)=135°の位置、分針は6×30=180°の位置にあり、その差がちょうど45°になるためです。
計算量と注意点
探索対象は最大720通りに限られるため、計算量はO(720)、つまり実質的に定数時間O(1)として扱えます。なお、浮動小数点数同士の比較は誤差の影響を受ける可能性があるため、実用上は許容誤差(イプシロン)を用いた比較に置き換えるとより堅牢になります。
-
C++で2つの日付間の日数を計算する方法【効率的なアルゴリズム解説】
この記事では、日付を表す3つの整数(DD-MM-YYYY形式)からなる2つの配列 date1[] と date2[] が与えられたとき、その2つの日付の間の日数を求める方法を解説します。 問題を理解するための例 入力 date1[] = {13, 3, 2021}, date2[] = {24, 5, 2023} 出力 802 説明 2つの日付の差は「2年」と「2か月(3月〜5月)」、そして「11日」です。これを日数に換算すると以下のようになります。 2 × 365 + (30 + 31) + 11 = 802 解法アプローチ 単純なアプローチ(ループによる方法) 最もシンプルな解決策は、開始
-
C++でアナログ時計の時針と分針の間の角度を求めるプログラム
アナログ時計の時刻を表す「時(hour)」と「分(minute)」の2つの値が与えられたとき、時針と分針がなす角度のうち、小さい方の角度を求める問題です。たとえば、hour = 12、minutes = 45 が入力された場合、答えは 112.5度 となります。解き方の考え方まず、それぞれの針がどれだけ回転するかを理解しましょう。時計盤は一周360度です。時針は12時間で360度回るため、1時間あたり30度動きます。さらに分の経過に合わせて少しずつ進むので、1分あたり0.5度ずつ移動します。分針は60分で360度回るため、1分あたり6度ずつ移動します。この性質をもとに、以下の手順で角度を計算で