3 분 소요

1. 상하좌우

문제

여행가 A는 N × N 크기의 정사각형 공간 위에 서 있다. 이 공간은 1 × 1 크기의 정사각형으로 나누어져 있다. 가장 왼쪽 위 좌표는 (1, 1)이며, 가장 오른쪽 아래 좌표는 (N, N)에 해당한다.

여행가 A는 상, 하, 좌, 우 방향으로 이동할 수 있으며, 시작 좌표는 항상 (1, 1)이다. 우리 앞에는 여행가 A가 이동할 계획이 적힌 계획서가 놓여 있다.

  • L: 왼쪽으로 한 칸 이동
  • R: 오른쪽으로 한 칸 이동
  • U: 위로 한 칸 이동
  • D: 아래로 한 칸 이동

이때, 여행가 A가 N × N 크기의 정사각형 공간을 벗어나는 움직임은 무시된다. 예를 들어 (1, 1)의 위치에서 L 혹은 U를 만나면 무시된다. 다음은 N = 5인 지도와 계획이다.

이코테 상하좌우

입력조건

  • 첫째 줄에 공간의 크기를 나타내는 N이 주어진다. (1<=N<=100)
  • 둘째 줄에 여행가 A가 이동할 계획서 내용이 주어진다. (1<=이동 횟수<=100)

출력조건

  • 첫째 줄에 여행가 A가 최종적으로 도착할 지점의 좌표(X,Y)를 공백으로 구분하여 출력한다.

입력예시

5
R R R U D D

출력예시

3 4

나의 코드

첫 번째 시도.

n = int(input())
route = list(input().split())

#출발 지점.(x,y)
   x=1
   y=1
   #L,R이 있으면 좌우, U,D가 있으면 위아래 방향으로 움직인다.
   #우리가 아는 좌표평면에서는 x축이 좌우 방향, y축이 위아래 방향을 결정하지만
   #행렬에서는 이에 대한 역할이 반대로 이루어진다.(1,1)->(1,2)행렬에서 보았을 때 column이 +1이 됌.
   #column+=1은 오른쪽으로 +=1 이다! 이에 혼동이 하지 않도록 유의하자.
   
   for direction in route:
       if 'R' in direction and y!=n:
           y+=1
       if 'L' in direction and y!=1:
           y-=1
       if 'U' in direction and x!=1:
           x-=1
       if 'D' in direction and x!=n:
           x+=1
        
print(x,y)

답안 예시

n = int(input())
x,y = 1,1
plans = input().split()

dx=[0,0,-1,1]
dy=[-1,1,0,0]
move_types = ['L','R','U','D']

for plan in plans:
    for i in range(len(move_types)):
        if plan==move_types[i]:
            nx=x+dx[i]
            ny=y+dy[i]
	if nx<1 or ny<1 or nx>n or ny>n:
        continue
    x,y = nx,ny

print(x,y)

🌝 Thinking

나의 코드는 내가 파이썬언어를 쓰는 사람인 것을 알 수 있는 것 같다.

답안코드는 c/c++와 같은 언어에서 구현을 하려면 다음과 같이 리스트(배열)을 이용하여 문자열 처리를 해야할 듯하다.

2. 시각

문제

정수 N이 입력되면 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 구하는 프로그램을 작성하시오.

예를 들어 1을 입력했을 때, 다음은 3이 하나라도 포함되어 있으므로 세어야 하는 시각이다.

  • 00시 00분 03초
  • 00시 13분 30초

반면에 다음은 3이 하나도 포함되어 있지 않으므로 세면 안되는 시각이다.

  • 00시 02분 55초

  • 01시 27분 45초

입력조건

  • 첫째 줄에 정수 N이 입력된다. (0<=N<=23)

출력조건

  • 00시 00분 00초부터 N시 59분 59초까지의 모든 시각 중에서 3이 하나라도 포함되는 모든 경우의 수를 출력한다.

입력예시

5

출력예시

11475

나의 코드

첫 번째 시도.

n = int(input())

result=0
#시계의 60진법을 for 구문을 이용하여 구현.
for _hour in range(n+1):
    for _min in range(60):
        for _sec in range(60):
            times = [str(_hour),str(_min),str(_sec)]          
            for time in times:
                if '3' in time:
                    result+=1
               
print(result)

이 문제를 보자마자 시계를 3중 for 구문을 이용하여 구현해보자!

라는 아이디어가 순식간에 떠올랐고 코드를 짜는 데까지 2분채 걸리지 않았다. (순간 나 자신 너무 기특…. 그러나)

fail

14400

의 결과가 나옴. 정답은 11475인데 무언가 세면 안될 것을 더 세어준 것 같았다.

두 번째 시도

n = int(input())

result=0
#시계의 60진법을 for 구문을 이용하여 구현.
for _hour in range(n+1):
 for _min in range(60):
     for _sec in range(60):
         times = [str(_hour),str(_min),str(_sec)]          
         for time in times:
             if '3' in time:
                 result+=1
                 break                            #break를 추가함.
print(result)
11475

정답!


🌝 Thinking

바보처럼 구현이 쉽게 할 수 있는 마음에 너무 들떠서 실수를 해버렸다.

times 배열에서 3이 있는가를 조사하기 위해서 times배열을 다시한번 순회하면서 3이 들어 있을 때마다 result+=1을 해주었다.

하지만 times는 배열을 순회하면서 3이 발견되는 즉시 break를 이용하여 times 배열 순회를 멈춰주어야한다.

그렇지 않으면 00시 13분 30초은 3이 포함된 시간이라 +1만 되어야 하지만 분과 초의 3을 각각 따로 카운트하게 되어 +2를 해버리기 때문이다.


답안 예시

h = int(input())

count=0
for i in range(h+1):
 for j in range(60):
     for k in range(60):
       if '3' in str(i)+str(j)+str(k):
     		count+=1
            
 print(count)

🌝 Thinking

나의 코드는 ‘3’이 들어간 시각을 찾기위해서 그 시각의 [‘시’, ‘분’, ‘초’]를 다음과 같이 리스트에 넣어서 처리 해주었다 . 하지만

답안코드는 그냥 시,분,초를 바로 str로 자료형을 변형하여 + 를 이용하여 쭉 연결하였다.

예를 들면 1시 30분 20초 -> 13020과 같이 그러면 따로 시각 내에서 순회할 필요도 없이 바로 ‘3’이 있는가를 조사하면 된다.

나의코드보다 안정적인 느낌이 든다…(후 열받는군 ♨)

💡 깨달은 점.

  1. 파이썬은 문자열 처리를 할 때, 타 언어에 비해 정말 수월하게 처리 할 수 있구나.
  2. 문자열을 순회하는 경험치가 아직 많이 부족한 것 같다. 문자열 문제를 더 다루어 보아야 겠다.

출처

이것이 코딩 테스트다 - 나동빈 저

댓글남기기