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

문제

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

출력(예시)

  1. 09:00

  2. 15:00

    ...

    Total: n번!

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

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

29개의 풀이가 있습니다. 1 / 3 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
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
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입니다.

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)
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

C#

            int count = 0;

            for(int i = 0; i <= 23; i++)
            {
                for(int j = 0; j <= 59; j++) {
                    double angleHour = ((360d / (12d * 60d)) * (i * 60d + j)) % 360d;
                    double angleMinute = (360d / 60d * (i * 60d + j)) % 360d;

                    double abs = Math.Abs(angleHour - angleMinute);

                    if (abs == 90d || abs == 270d)
                    {
                        count++;
                        Console.WriteLine("{0:d4} {1:d2}:{2:d2}", count, i, j);
                    }
                }
            }
            Console.WriteLine("Total: {0}번!", count);

결과값 : 0001 03:00 0002 09:00 0003 15:00 0004 21:00 Total: 4번!

이게 분단위라 정확히 90도는 4번 밖에 안 나오네요.

저는 분단위로 하면 4번밖에 안나온다는 걸 깨닫지 못한채 몇시간 삽질만 했네요..ㅠㅠ - ken choi, 2017/03/30 16:08 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

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

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


언어별 풀이 현황
전 체 x 29
python x 17
cpp x 2
cs x 3
objectivec x 1
ruby x 1
java x 4
기 타 x 1