← Назад к вопросам
Угол между стрелками часов
1.0 Junior🔥 151 комментариев
#Другое#Основы Java
Условие
Напишите программу, которая вычисляет угол между часовой и минутной стрелкой часов.
Примеры
- 12:00 → 0 градусов
- 12:15 → 90 градусов (минутная на 3, часовая чуть дальше 12)
- 3:00 → 90 градусов
- 6:00 → 180 градусов
- 9:45 → 22.5 градусов
Формулы
- Минутная стрелка: 6 градусов за минуту (360/60)
- Часовая стрелка: 0.5 градусов за минуту (30/60)
- Часовая стрелка: 30 градусов за час (360/12)
Требования
- Верните меньший из двух возможных углов
- Угол должен быть положительным
- Обработайте граничные случаи (полдень, полночь)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Угол между стрелками часов
Это интересная геометрическая задача, которая часто встречается на собеседованиях. Ключ к решению — понимание того, как движутся часовая и минутная стрелки.
Основные принципы
Минутная стрелка:
- Полный оборот: 360° за 60 минут
- За одну минуту: 360° / 60 = 6° за минуту
- Положение:
minutes * 6
Часовая стрелка:
- Полный оборот: 360° за 12 часов
- За один час: 360° / 12 = 30° за час
- За одну минуту: 30° / 60 = 0.5° за минуту
- Положение:
(hours % 12) * 30 + minutes * 0.5
Угол между стрелками:
- Разница:
|minuteAngle - hourAngle| - Если больше 180°, возьмём меньший угол:
360 - angle
Решение
public class ClockAngle {
public static double getAngle(int hours, int minutes) {
// Валидация входных данных
if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) {
throw new IllegalArgumentException(
"Часы должны быть 0-23, минуты должны быть 0-59"
);
}
// Конвертируем в 12-часовой формат
hours = hours % 12;
// Вычисляем положение минутной стрелки (в градусах)
double minuteAngle = minutes * 6;
// Вычисляем положение часовой стрелки (в градусах)
// Часовая стрелка движется не только по часам, но и по минутам
double hourAngle = hours * 30 + minutes * 0.5;
// Вычисляем разницу
double angle = Math.abs(hourAngle - minuteAngle);
// Возвращаем меньший из двух углов
if (angle > 180) {
angle = 360 - angle;
}
return angle;
}
public static void main(String[] args) {
System.out.println(getAngle(12, 0)); // 0.0 ✓
System.out.println(getAngle(3, 0)); // 90.0 ✓
System.out.println(getAngle(6, 0)); // 180.0 ✓
System.out.println(getAngle(9, 0)); // 90.0 ✓
System.out.println(getAngle(12, 15)); // 82.5 ✓
System.out.println(getAngle(9, 45)); // 22.5 ✓
System.out.println(getAngle(3, 15)); // 7.5 ✓
}
}
Пошаговый расчёт примеров
Пример 1: 12:00
Минутная стрелка: 0 * 6 = 0°
Часовая стрелка: (12 % 12) * 30 + 0 * 0.5 = 0 * 30 + 0 = 0°
Разница: |0 - 0| = 0°
✓ Результат: 0°
Пример 2: 12:15
Минутная стрелка: 15 * 6 = 90°
Часовая стрелка: (12 % 12) * 30 + 15 * 0.5 = 0 * 30 + 7.5 = 7.5°
Разница: |7.5 - 90| = 82.5°
✓ Результат: 82.5°
Пример 3: 3:00
Минутная стрелка: 0 * 6 = 0°
Часовая стрелка: (3 % 12) * 30 + 0 * 0.5 = 3 * 30 + 0 = 90°
Разница: |90 - 0| = 90°
✓ Результат: 90°
Пример 4: 6:00
Минутная стрелка: 0 * 6 = 0°
Часовая стрелка: (6 % 12) * 30 + 0 * 0.5 = 6 * 30 + 0 = 180°
Разница: |180 - 0| = 180°
✓ Результат: 180°
Пример 5: 9:45
Минутная стрелка: 45 * 6 = 270°
Часовая стрелка: (9 % 12) * 30 + 45 * 0.5 = 9 * 30 + 22.5 = 270 + 22.5 = 292.5°
Разница: |292.5 - 270| = 22.5°
✓ Результат: 22.5°
Визуализация
12:00 12:15
12 12
9 3 9 3
6 6
Угол = 0° Угол = 82.5°
(обе стрелки на 12) (минутная на 3, часовая чуть дальше)
3:00 6:00
12 12
9 3 ← 9 3
6 6 ←
Угол = 90° Угол = 180°
(часовая на 3, (стрелки напротив друг друга)
минутная на 12)
9:45
12
9 ← 3
6
Угол = 22.5°
(обе стрелки близко к 9, минутная впереди)
Альтернативное решение (более компактное)
public class ClockAngleCompact {
public static double getAngle(int hours, int minutes) {
double minuteAngle = minutes * 6;
double hourAngle = (hours % 12) * 30 + minutes * 0.5;
double angle = Math.abs(hourAngle - minuteAngle);
return Math.min(angle, 360 - angle);
}
}
С использованием методов обработки ошибок
public class ClockAngleSafe {
private static final int MINUTES_IN_HOUR = 60;
private static final int HOURS_IN_CLOCK = 12;
private static final double MINUTE_ANGLE_PER_MINUTE = 6.0;
private static final double HOUR_ANGLE_PER_HOUR = 30.0;
private static final double HOUR_ANGLE_PER_MINUTE = 0.5;
private static final int FULL_ROTATION = 360;
public static double getAngle(int hours, int minutes) {
validateInput(hours, minutes);
double minuteAngle = calculateMinuteAngle(minutes);
double hourAngle = calculateHourAngle(hours, minutes);
return calculateAngleBetween(minuteAngle, hourAngle);
}
private static void validateInput(int hours, int minutes) {
if (hours < 0 || hours >= 24) {
throw new IllegalArgumentException("Часы должны быть 0-23");
}
if (minutes < 0 || minutes >= MINUTES_IN_HOUR) {
throw new IllegalArgumentException("Минуты должны быть 0-59");
}
}
private static double calculateMinuteAngle(int minutes) {
return minutes * MINUTE_ANGLE_PER_MINUTE;
}
private static double calculateHourAngle(int hours, int minutes) {
hours = hours % HOURS_IN_CLOCK;
return hours * HOUR_ANGLE_PER_HOUR + minutes * HOUR_ANGLE_PER_MINUTE;
}
private static double calculateAngleBetween(double angle1, double angle2) {
double difference = Math.abs(angle1 - angle2);
return Math.min(difference, FULL_ROTATION - difference);
}
}
Тестирование
public class ClockAngleTest {
public static void main(String[] args) {
test(12, 0, 0.0);
test(3, 0, 90.0);
test(6, 0, 180.0);
test(9, 0, 90.0);
test(12, 15, 82.5);
test(9, 45, 22.5);
test(3, 15, 7.5);
test(6, 30, 15.0);
test(15, 0, 90.0); // 3:00 PM → 90°
test(21, 30, 75.0); // 9:30 PM → 75°
}
private static void test(int hours, int minutes, double expected) {
double result = ClockAngle.getAngle(hours, minutes);
boolean passed = Math.abs(result - expected) < 0.01;
System.out.printf("%d:%02d → %.1f° (ожидали %.1f°) %s%n",
hours, minutes, result, expected, passed ? "✓" : "✗");
}
}
Сложность
Временная сложность: O(1) — только арифметические операции
Пространственная сложность: O(1) — используются только переменные
Ключевые моменты
- Часовая стрелка движется непрерывно — она не прыгает от часа к часу, а движется плавно
- Используйте модуль —
hours % 12для обработки 12-часового формата - Возьмите минимум — из двух возможных углов (меньший и больший)
- Проверьте граничные случаи — 12:00 (полдень/полночь), 6:00 (противоположные стрелки)