본문 바로가기
프로그래밍 파이썬

[백준 BAEKJOON] 1063번 킹

by st-og 2023. 2. 11.

문제 설명

소스코드

  1. k,s,n=map(str,input().split())
  2. n=int(n)
  3.  
  4. k=[ord(k[0]),int(k[1])]
  5. s=[ord(s[0]),int(s[1])]
  6.  
  7. for i in range(n):
  8.     com=input()
  9.     tmp_k=k.copy()
  10.     tmp_s=s.copy()
  11.     #커맨드 이동 명령
  12.     if 'R' in com:
  13.         k[0]+=1
  14.     elif 'L' in com:
  15.         k[0]-=1
  16.     if 'T' in com:
  17.         k[1]+=1
  18.     elif 'B' in com:
  19.         k[1]-=1
  20.  
  21.     if k[0]==73 or k[0]==64 or k[1]==0 or k[1]==9:
  22.         k=tmp_k
  23.  
  24.     if k==s:
  25.         if tmp_k[0]-k[0]==-1:
  26.             s[0]+=1
  27.         elif tmp_k[0]-k[0]==1:
  28.             s[0]-=1
  29.         if tmp_k[1]-k[1]==-1:
  30.             s[1]+=1
  31.         elif tmp_k[1]-k[1]==1:
  32.             s[1]-=1
  33.         if s[0]>72 or s[0]<65 or s[1]<1 or s[1]>8:
  34.             k=tmp_k
  35.             s=tmp_s
  36.  
  37. print(chr(k[0])+str(k[1]))
  38. print(chr(s[0])+str(s[1]))

문제 접근

이 문제에서 제일 중요한 키워드는 "무시"인 것 같다.

범위를 벗어나는 입력은 말 그대로 무시를 해야 한다.

무시를 하기 위해선 초기의 좌표를 기억해둔 후 무시해야 하는 인풋이 들어왔을 때 다시 초기의 좌표로 되돌리면 된다.

그리고 왕과 돌이 만났을 경우 왕이 어떤 이동을 했는지 알아야 돌을 같은 방향으로 움직일 수 있다.

 

킹과 돌을 움직인 후 범위를 벗어나면 처리한다는 접근보단

범위 안에서 움직이게 하고 범위를 벗어나면 다시 되돌린다는 접근으로 풀면 쉬울것 같다.

코드 리뷰

4~5: 좌표 A~H를 아스키코드로 만들어 좌표 이동을 편하게 만들었고 리스트로 만들어 관리하기 편하게 만들었다.

9~10: "무시"를 하기 위한 초기 좌표 저장을 위해 tmp변수에 저장을 했다.

12~19: 입력받은 커맨드대로 킹이 이동한다.

21~22: 킹이 정해진 범위를 벗어나는 경우, 즉 "무시"를 해야 하는 경우이다. k=tmp_k를 통해 k를 초기화한다.

24: 킹과 돌의 좌표가 같아진 경우, 킹이 돌쪽으로 이동했다는 것을 뜻한다.

25~32: 킹의 이동 방향을 파악하기 위해 이동한 킹의 좌표와 기존의 킹의 좌표를 빼기 연산을 했다.

             ex)빼기 연산의 값이 마이너스라면 R 또는 T의 입력이 있었다는 것을 알게 된다.

33~35: 움직인 돌이 정해진 범위를 벗어 난다면 왕과 돌은 그 입력을 무시해야 하기에 둘 다 초기화시킨다.

37~38: 출력 전에 다시 아스키와 str형으로 변환 후 출력한다.

실패 유형

처음엔 문제를 유심히 읽지 않아 범위 밖으로 나갈 경우 건너뛰라는 힌트를 신경을 못썼다.

그래서 이중 배열을 만들어 실제 체스판처럼 만들어 돌려도 보고

모든 이동 if문에 추가적인 if를 걸어 범위를 벗어나면 다시 빼기 연산을 하도록도 해봤다.

그리고 범위를 벗어났는지 체크하는 함수를 만들어 벗어났다면 빼도록 했다.

실패 이유

제일 큰 실패 이유는 실제로 체스말이 움직인다는 생각을 했다는 것이다.

처음 그 생각에 꽂히니까 체스 말을 이동 후 범위 밖이면 다시 뒤로 보낸다 라는 생각으로 연결 됐다.

그러다 보니 왕 하나면 움직이는 건 여러 if문을 통해 더러운 코드로 가능은 했지만 돌까지 함께 컨트롤이 되기엔 힘들었다.

 

배운 것

문제를 잘 읽어야겠다. 문제 해결을 위해선 문제 파악이 제일 중요하다는 것을 또 한 번 느꼈다.

실제 결과대로 생각하는 것이 아닌 그 결과를 나타내기 위해선 어떻게 해야 하는지에 대해 더 생각을 하도록 노력하자.

 

list를 그대로 복사하고 싶다면 copy함수를 쓰자

그냥 다른 변수에 넣게 된다면 메모리 주소까지 그대로 저장되기 때문에 값이 변경될 경우 같이 변경된다.