카테고리 없음
[알고리즘] 아날로그 시계 문제
코딩연습중
2026. 2. 13. 16:50
https://school.programmers.co.kr/learn/courses/30/lessons/250135
프로그래머스에서 알고리즘 연습 중 기록을 위해 정리.
시침&초침, 분침&초침이 겹칠 때 알람이 울리는데, 처음에 어떻게 풀지 고민함.
초침이 시침&분침보다 뒤에 있다가 앞으로 넘어가는 부분을 찾아야겠다는 생각을 함.
초침이 뒤(왼쪽?)에 있는 경우를 -, 앞에 있는 경우를 +로 쳤을 때, 이게 바뀌면 카운트를 해야겠다고 생각했음..
그치만 구현이 까다로울 것 같아 아래의 방식으로 했더니 도저히 답이 나오지 않음.
class Solution {
public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
int answer = 0;
double init_h = (double)(h1*60*60 + m1*60 + s1)/(12*60);
double init_m = (double)(m1*60 + s1)/60;
double init_s = (double)s1;
double prev_h = init_h;
double prev_m = init_m;
double prev_s = init_s;
boolean isFlag = false;
// curr_m - curr_s <= 1 및 curr_h - curr_s <= 1인 경우에 봐야 함.
if( ((prev_h - prev_s >= 0) && (prev_h - prev_s <= 1)) || ((prev_m - prev_s >= 0) &&(prev_m - prev_s <= 1))){
isFlag = true;
}
// 알람 울리는지 판단
if(prev_h==prev_s || prev_m==prev_s){
answer += 1;
isFlag = false;
}
// 본격적 비교
for(int i = 1; i <= ((h2-h1)*60*60 + (m2-m1)*60 + s2-s1); i++){
double curr_h = (prev_h + 1/(12*60))%60;
double curr_m = (prev_m + 1/60)%60;
double curr_s = (prev_s + 1)%60;
if (isFlag){
answer += 1;
isFlag = false;
}
if( ((curr_h - curr_s >= 0) && (curr_h - curr_s <= 1)) || ((curr_m - curr_s >= 0) &&(curr_m - curr_s <= 1))){
isFlag = true;
}
prev_h = curr_h;
prev_m = curr_m;
prev_s = curr_s;
}
return answer;
}
}
class Solution {
public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
int answer = 0;
double init_h = (double)(h1*60*60 + m1*60 + s1)/(12*60);
double init_m = (double)(m1*60 + s1)/60;
double init_s = (double)s1;
double prev_h = init_h;
double prev_m = init_m;
double prev_s = init_s;
boolean h_Flag = false;
boolean m_Flag = false;
// curr_m - curr_s <= 1 및 curr_h - curr_s <= 1인 경우에 봐야 함.
if((prev_h - prev_s >= 0) && (prev_h - prev_s <= 1)){
h_Flag = true;
}
if((prev_m - prev_s >= 0) &&(prev_m - prev_s <= 1)){
m_Flag = true;
}
// 알람 울리는지 판단
if(prev_h==prev_s || prev_m==prev_s){
answer += 1;
h_Flag = false;
m_Flag = false;
}
// 본격적 비교
for(int i = 1; i <= ((h2-h1)*60*60 + (m2-m1)*60 + s2-s1); i++){
double curr_h = (prev_h + 1/(12*60))%60;
double curr_m = (prev_m + 1/60)%60;
double curr_s = (prev_s + 1)%60;
// 완전히 겹칠 때
if(curr_h == curr_m && curr_m == curr_s){
answer += 1;
h_Flag = false;
m_Flag = false;
prev_h = curr_h;
prev_m = curr_m;
prev_s = curr_s;
continue;
}
// flag 걸렸을 때
if (h_Flag){
answer += 1;
h_Flag = false;
}
if(m_Flag){
answer += 1;
m_Flag = false;
}
if((curr_h - curr_s >= 0) && (curr_h - curr_s <= 1)){
h_Flag = true;
}
if((curr_m - curr_s >= 0) &&(curr_m - curr_s <= 1)){
m_Flag = true;
}
prev_h = curr_h;
prev_m = curr_m;
prev_s = curr_s;
}
return answer;
}
}
이렇게 했더니

class Solution {
public int solution(int h1, int m1, int s1, int h2, int m2, int s2) {
int answer = 0;
double init_h = (double)(h1*60*60 + m1*60 + s1)/120;
double init_m = (double)(m1*60 + s1)/10;
double init_s = (double)s1*6;
double prev_h = init_h;
double prev_m = init_m;
double prev_s = init_s;
boolean h_Flag = false;
boolean m_Flag = false;
// curr_m - curr_s <= 1 및 curr_h - curr_s <= 1인 경우에 봐야 함.
if(diff360(prev_h, prev_s) <= 6){
h_Flag = true;
}
if(diff360(prev_m, prev_s) <= 6){
m_Flag = true;
}
// 알람 울리는지 판단
if(prev_h==prev_s || prev_m==prev_s){
answer += 1;
h_Flag = false;
m_Flag = false;
}
// 본격적 비교
for(int i = 1; i <= ((h2*60*60 + m2*60 + s2) - (h1*60*60 + m1*60 + s1)); i++){
double curr_h = (prev_h + 1.0/(120))%360;
double curr_m = (prev_m + 1.0/10)%360;
double curr_s = (prev_s + 1.0*6)%360;
// 완전히 겹칠 때
if( curr_h == curr_m && curr_m == curr_s){
answer += 1;
h_Flag = false;
m_Flag = false;
prev_h = curr_h;
prev_m = curr_m;
prev_s = curr_s;
continue;
}
// flag 걸렸을 때
if (h_Flag){
answer += 1;
h_Flag = false;
}
if(m_Flag){
answer += 1;
m_Flag = false;
}
// flag 걸기
if(diff360(curr_h, curr_s) <= 6){
h_Flag = true;
}
if(diff360(curr_m, curr_s) <= 6){
m_Flag = true;
}
prev_h = curr_h;
prev_m = curr_m;
prev_s = curr_s;
}
return answer;
}
static boolean eq(double a, double b) {
return Math.abs(a - b) < 1e-9;
}
static double diff360(double a, double b) {
return (a - b + 360.0) % 360.0; // 0 <= 결과 < 360
}
}
교차판정이 맞는 것 같음
하 그리고 완전히 겹치는 경우는 저렇게 계산하면 될까,,?싶음
소수 비교가 정확할지 모르겠는데,,, 다음에 다시 이어서 풀어봐야지