시침과 분침이 직각이 되는 순간은?

문제

일반적인 1부터 12까지 아라비아 숫자가 적혀있는 시계가 있습니다.
이 시계는 오전 12:00 정각에 작동하기 시작하여 하루동안 움직이게 되어있습니다.
이 때 시침과 분침이 직각이 될 때의 시간을 hh:mm 형태로 나타내고 하루동안 직각이 된 총 횟수를 구해보세요!

출력(예시)

  1. 09:00

  2. 15:00

    ...

    Total: n번!

시간표현은 오전, 오후가 아닌 24시 방식으로 써주세요!

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

32개의 풀이가 있습니다. 1 / 4 Page

#!/usr/bin/env python
#-*- coding: utf-8 -*-
'''
시침은 하루에 2회전, 분침은 하루에 24회전 한다.
같은 방향으로 회전하므로 시침에 대한 분침의 "상대적인" 회전수는
하루에 24-2 = 22회전이다.
시침과 분침이 직각을 이루는 경우는 분침이 시침에 대해 다음과 같은 회전수를
했을 경우이다.
1/4, 3/4, 1+1/4, 1+3/4, ... , 21+1/4 , 21+3/4
따라서 하루에 총 44번 직각을 이룬다는 것을 알 수 있다.
위의 수열을 일반항으로 표현하면
(2n-1)/4 (1<=n<=44)이다.
상대적인 1회전에 걸리는 시간은 24/22 = 12/11 시간이고,
위의 일반항에 12/11을 곱하면 24시간중 직각을 이루는 시간의 일반항이 나온다.
즉,
3(2n-1)/11 (1<=n<=44)
위의 결과값은 시간이므로 프로그램에서는 이를 시간과 분으로 적절히 변환해서
표현하면 되겠다.
예) 3.25시 -> 3:15
'''
for n in range(1, 45):
    h=(6*n-3)/11.0
    m = (h-int(h))*60
    print "%02d:%02d"%(h,m)
print "Total:44번!"
오..... 코딩보다도 수학적으로 푸셨네요 - 취미로재미로, 2016/01/27 16:47 M D
풀이 감사합니다. 저도 거의 같은 방법으로 풀었습니다. 위의 설명이 훨씬 간결합니다만, 위의 설명으로 이해하기 어려운 부분은 각속도로 설명한 제 풀이 http://codingdojang.com/scode/487?answer=7093#answer_7093 를 참조하시기 바랍니다. 누구든지 이해할 수 있게 설명하는 바람에 좀 길지만 이해하실 수 있으리라 생각합니다. - 예강효빠, 2017/05/07 13:57 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
hr_angle= 0
count=0
for h in range(24):
    min_angle=0
    if hr_angle>=360-1.0/12.0: hr_angle = 0

    for m in range(360):
        angle=abs(min_angle-hr_angle)
        if angle>=90.0-0.42 and angle<=90.42 or angle>=270.0-0.42 and angle<=270.42:
            print "%0.2d:%0.2d"%(h,m/6); count+=1
        min_angle += 1
        hr_angle += 1.0/12.0

print "Total: %d times!"%count

``````출력결과입니다.
00:16
00:49
01:21
01:54
02:27
03:00
03:32
04:05
04:38
05:10
05:43
06:16
06:49
07:21
07:54
08:27
09:00
09:32
10:05
10:38
11:10
11:43
12:16
12:49
13:21
13:54
14:27
15:00
15:32
16:05
16:38
17:10
17:43
18:16
18:49
19:21
19:54
20:27
21:00
21:32
22:05
22:38
23:10
23:43
Total: 44 times!
좋은 풀이 따라하고 싶은데 이해가 잘 안됩니다ㅠㅠ 왜 1.0/12.0을 빼줘야 하는지요? 0.42 는 대체 어디서 온 숫자인가요? 상세히 설명해주시는 분 복받으실거예요 - ken choi, 2017/03/28 13:46 M D
1/12 곱하기 12 하면 1이라는 정수가 나옵니다. 하지만 저는 분침이 1도 움직일때 시침이 1/12 도 가게했습니다. 그런데 1/12가 무리수여서 1/12씩 12번 더하면 1로 떨저지지 않습니다. 그래서 분침이 60번씩 12번 돌면 시침이 360도가 되는게 아닌 359.99999999998795 이렇게 나오는데 사실상 저때가 12시:00, 즉 분침이 60*12번 돌았을 때입니다. if hr_angle>=360 라고 하면 분침이 359.99999999998795(사실상360) 에서 0도로 초기화가 안됩니다. 359.99999999998795 는 360 - 1/12 보다는 크므로 재때에 0도로 초기화가 됩니다. angle도 같은 맥락에서 0.42를 범위로 준겁니다. 분침이 1도 움직일때 시침이 소수점으로 움직이니 정확히 90도 라는 정수가 안나오므로 90.xx가 걸릴 범위로 잡아준 겁니다. - Noh Hun, 2017/03/28 20:16 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

시침과 분침이 겹쳐있는 상태에서 다음 겹친 상태로 가는데는 720/11 분이 걸리고, 그 사이에 두 번의 직각이 되는 시점이 있습니다. (180/11, 540/11) 하루는 1440분이니 시침과 분침이 겹치는 시점은 총 22회 있고, 따라서 44회의 직각이 있을 수 있습니다.

따라서 초항이 180/11, 공차가 360/11 인 등차수열로 해당 시점의 분을 구할 수 있고, 분단위의 시간을 00시00분 포맷으로 표시해주면 됩니다.

from fractions import Fraction

def format_time(p):
    return "{:02d}:{:02d}".format(*divmod(int(p), 60))

a1 = Fraction(180, 11)
k = Fraction(360, 11)
for i in range(44):
    print(format_time(a1 + k * i))

결과는 다음과 같습니다.

00:16
00:49
01:21
01:54
02:27
03:00
03:32
04:05
04:38
05:10
05:43
06:16
06:49
07:21
07:54
08:27
09:00
09:32
10:05
10:38
11:10
11:43
12:16
12:49
13:21
13:54
14:27
15:00
15:32
16:05
16:38
17:10
17:43
18:16
18:49
19:21
19:54
20:27
21:00
21:32
22:05
22:38
23:10
23:43
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Python 3.4.2 각속도 개념이해가 필요합니다. 위키피디아-각속도를 참조하세요.

각속도란 변화시간내에 몇도나 돌아갔나를 나타내는 개념입니다. 속도의 거리가 각도로 바뀌어 있다고 생각하면 쉽습니다.

즉, 속도 = 거리/시간 이듯이 각속도 = 각도/시간 입니다.

아시다시피 분침은 시침보다 빨리 돕니다. 즉 분침이 시침보다 각속도가 빠릅니다. (흡사 거북이와 토끼)

그리고 분침과 시침의 속도는 모두 등속도입니다. (가속도가 아닙니다. 매우 중요)

얼마나 빠를까요? 하루를 기준으로 생각해봅시다. 그럼 0시 시침과 분침이 같은 출발선에 서 있다가 뛰기 시작한다면

하루에 분침은 24바퀴를 돕니다. 시침은 두바퀴를 돌죠. 즉, 분침각속도 = 24바퀴/하루, 시침각속도 = 2바퀴/하루 입니다.

즉, 0시에서 다음날 0시가 되는, 하루라는 동일한 기준시점에 분침은 시침보다 22바퀴를 더 앞서 달리고 있는 겁니다. 이해가시죠?

그럼 차근차근 0시부터 생각해보면,

출발선에서 "땅"하고 시작하면 분침은 휭~하고 앞서 달리기 시작합니다.

(1) 그러다 어느 시각에 분침이 시침을 1/4바퀴 앞섭니다. 즉, 1/4 * 바퀴(360도) = 90도 를 앞섭니다.

자 계속 달립니다. 분침은 계속 시침과 간격을 벌립니다.

(2) 그러다 어느 시각에 분침이 시침을 3/4바퀴 앞섭니다. 즉, 3/4 * 바퀴(360도) = 270도 를 앞섭니다.

자 이제는 분침은 이미 한바퀴를 돌았습니다. 그리고 시침을 재쳐버립니다. 그리고서

(3) 그러다 어느 시각에 분침이 시침을 한바퀴와 1/4바퀴 앞섭니다. 즉, 5/4 * 바퀴(360도) = 450도 를 앞섭니다.

.

.

이렇게 계속 달리면 결국 분침은 계속 앞서 나가게 되고 다음날 0시가 되는 시점에 22바퀴를 앞서게 된다고 했으니 그전에는

(44) 마지막으로 어느 시각에 분침이 시침을 21바퀴와 3/4바퀴 앞섭니다.

즉, 분침이 한바퀴를 앞서갈때마다 2번 직각을 이루고 총 44번 직각을 이룹니다.

이해가시나요? 그럼, 이제 단위를 바꿔 봅시다.

어느 시각이라고 했으니 시간단위로 바꿉니다.

분침각속도 = 24바퀴/하루 = 24*360도/24시간 = 360 도/시간

시침각속도 = 2바퀴/하루 = 2*360도/24시간 = 30 도/시간

T1 에 1/4 * 360도 앞서고

T2 에 3/4 * 360도 앞서고

T3 에 5/4 * 360도 앞서고

T4 에 7/4 * 360도 앞서고

.

.

Tn 에 (2n-1)/4 * 360 도 를 앞서게 됩니다. 맞죠? 이로서 앞서는 직각도 수열의 일반공식입니다.

각속도 = 각도/시간 이라고 했으니 각도 = 각속도*시간 입니다. 그리고 시간 = 각도/각속도 입니다.

그런데 어느 시각에 라고 했으니 시간은 동일합니다.

그렇다면 분침각도 - 시침각도 = 직각도의 일반공식 이란 얘기고,

이건 (분침각속도 - 시침각속도)*직각을 이루는 시간 = 직각도의 일반공식 이며

따라서 직각을 이루는 시간 = 직각도의 일반공식/(분침각속도 - 시침각속도) 입니다. (여기까지 이해하셨나요?)

대입해봅니다.

(360 도/시간 - 30 도/시간)Tn = (2n-1)/4 * 360도

Tn = (2n-1)/4 * 360/330

= (2n-1)/4 * 12/11

= 3*(2n-1) / 11

라는 직각을 이루는 시간의 일반공식이 나옵니다 여기다가 1<= n <=44 를 integer 를 대입하면 됩니다.

m_turn = 24 # 분침 하루에 도는 바퀴
h_turn = 2 # 시침 하루에 도는 바퀴
times_right = (m_turn - h_turn) * 2 # 한시간에 2번 직각을 이룰때 하루에 모두 몇번?
print("{} times".format(times_right))
for i in range(1, times_right+1):
    hour = (3*(2*i-1))/11.0 # 만나는 시간을 floating 으로
    min = (hour - int(hour)) * 60 # 소숫점부분만 분단위로
    print("%2d:%02d"%(hour,min)) # **:** 단위로 출력
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

python입니다.

from fractions import Fraction
from math import floor

total = 0

for i in range(90, 7920, 180):
    total += 1
    minute = Fraction(i*2, 11)
    hour = floor(Fraction(i, 330))
    print(hour, '시', minute-60*hour, '분')

print('총', total, '번')

해설 :

0시를 기준으로 시침과 분침이 회전한 각도의 차이를 A라 합시다. 그러면 시침과 분침이 직각일 때 A의 값으로 가능한 것은

  • 90도 - 0시 180/11 분
  • 270도 - 0시 540/11 분
  • (...)
  • 7830도 - 23시 480/11 분

가 됩니다. A를 5.5로 나누면 0시를 기준으로 몇 분인지 구할 수 있습니다.

여기선 분수 표현을 위해 fractions 모듈을 사용했습니다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
def Clock ( i, j ):
    print ("" if i>9 else "0") + str(i) + ":" + ("" if j>9 else "0") + str(j)   

su = 0
bfr = 0

for i in range(24) :
  for j in range (60) :
    a = abs (  (i if (i<12) else (i-12)) * 5 * 6 + 30 * j / 60 - j * 6 )
    if a > 180 : a = 360 - a
    if ( a >= 90 and bfr < 90 ) or ( a <= 90 and bfr > 90 ) :       
        Clock( i, j )
        su += 1 
    bfr = a

print "Total: %d times!"%su


※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
void exce92()
{
    int hh = 0, mm = 0;
    int dgr = 0;
    int count = 0;

    for (int i = 0; i < 720; i++)
    {
        mm += 2;
        if (mm == 60)
        {
            mm = 0;
            hh++;
        }

        dgr = (dgr + 11) % 360;

        if (dgr == 90 || dgr == 270)
        {
            count++;
            printf("%d. %02d:%02d\n", count,hh, mm);
        }
    }
    printf("총 %d번 90도가 됩니다.\n", count);
}

매 분마다 체크를 하니까 생각보다 90도가 되는 횟수가 적네요..

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
res = filter(lambda x : abs((30*(x[0]%12) + 1/2*x[1]) - 6*x[1]) == 90,[ (x,y) for x in range(0,24) for y in range(0,60) ])

for x, y in res :
    print '%02d:%02d' % (x,y)
print "total : %d" % len(res)

한줄코드 도전!

시침이 움직이는거 고려하지 않으셧네요;; - 승학, 2015/08/17 15:55 M D
답변 감사합니다. (30*(x[0]%12) + 1/2*x[1])에서 1/2*x[1] <-- 분침 이동을 고려한 것입니다. 60분 중에 30분을 넘으면 좌우 대칭이 되므로, (60/2)*x + 1*(1/2)*y 한겁니다. - BaekSeungWoo, 2015/08/18 17:58 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

제 시계는 분단위로 움직입니다 또각 또각

oneDayMunite = 24*60; # 하루 총 분의 양
h = 0
ma = 0
ha = 0
m = 0
result =[];
for i in range(0,oneDayMunite+1):   
    #시간 증가
    if(m > 0 and m%60 == 0):
        ma = 0 #시간이 지나면 분침각도는 0
        m = 0 #시간이 지나면 0분부터~
        h = h+1 #시간증가
        if(h == 12): #12시가 되면은 각도가 0
            ha = 0
    #결과 넣기
    if(abs(ma-ha) == 90 or abs(ma-ha) == 270):
        result.append(str(h).zfill(2) +":"+ str(m).zfill(2))
    #결과확인용 debug
    print(  str(abs(ma-ha)) + " " + str(h) +":"+ str(m) + " ha:"+str(ha) +" ma:"+ str(ma) )
    ma = ma+6 #분침은 6도 씩 증가
    ha = ha+0.5 #시침은 0.5도 씩 증가
    m = m+1 #1분증가

for x in result:
    print(x)
print("총 " + str(len(result)) + "번 !")
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

1분 이동시 분침 이동각도 = 6 1분 이동시 시침 이동각도 = 0.5 1시간 이동시 시침 이동각도 = 30

90 또는 270도가 될때마다 카운트 증가

result = 0

for hour in range(0, 24) :
    for min in range(0, 60) :
        h_degree = ((hour * 30) + (min * 0.5)) % 360
        m_degree = min * 6

        gap = abs(h_degree - m_degree)

        if gap == 90 or gap == 270 :
            print(hour , min, sep=" : ")
            result += 1

print("total " , result)
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 32
python x 19
cpp x 2
cs x 3
objectivec x 1
ruby x 1
java x 5
기 타 x 1