728x90
왕실의 나이트
A. 문제
8 x 8 좌표평면.
나이트는 L자 형태로만 이동할 수 있고, 정원 밖으로 나갈 수 없다.
수평으로 두 칸 이동한 뒤에 수직으로 한 칸 이동하기수직으로 두 칸 이동한 뒤에 수평으로 한 칸 이동하기
행 위치는 1~8로 표현하고, 열 위치는 a~h로 표현한다.
나이트가 이동할 수 있는 경우의 수를 출력하라.
a. 예를 들면.
나이트의 위치가 a1일 때 이동할 수 있는 경우의 수는 2가지다.오른쪽으로 두 칸 이동 후 아래로 한 칸 이동하기 (c2)아래로 두 칸 이동 후 오른쪽으로 한 칸 이동하기 (b3)
b. 입력 조건
첫째 줄에 8x8 좌표 평면상에서 현재 나이트가 위치한 곳의 좌표를 나타내는 두 문자로 구성된 문자열이 입력된다. 문자는 a1과 같이 열행으로 이뤄진다.
c. 출력 조건
첫째 줄에 나이트가 이동할 수 있는 경우의 수를 출력하라.
더보기
# 현재 나이트의 위치 입력받기
input_data = input()
row = int(input_data[1])
column = int(ord(input_data[0])) - int(ord('a')) + 1
# 나이트가 이동할 수 있는 8가지 방향 정의
steps = [(-2, -1), (-1, -2), (1, -2), (2, -1), (2, 1), (1, 2), (-1, 2), (-2, 1)]
# 8가지 방향에 대하여 각 위치로 이동이 가능한지 확인
result = 0
for step in steps:
# 이동하고자 하는 위치 확인
next_row = row + step[0]
next_column = column + step[1]
# 해당 위치로 이동이 가능하다면 카운트 증가
if next_row >= 1 and next_row <= 8 and next_column >= 1 and next_column <= 8:
result += 1
print(result)
게임 개발
A. 문제
캐릭터가 있는 장소는 1x1 크기의 정사각형으로 이뤄진 NxM 크기의 직사각형이다.
N세로 크기
M가로 크기
각각의 칸은 육지 또는 바다이다.맵의 각 칸은 (A, B)로 표현한다.A는 북쪽으로부터 떨어진 칸의 개수 (row)B는 서쪽으로부터 떨어진 칸의 개수 (column)캐릭터는 동서남북 중 한 곳을 바라본다.캐릭터는 상하좌우로 움직이며, 바다에는 갈 수 없다.캐릭터의 움직임현재 방향을 기준으로 왼쪽 방향(반시계 90º 회전)부터 갈 곳을 정한다.바라본 위치가 아직 가보지 못한 곳이라면 바라보는 방향으로 전진한다.바라본 방향에 가보지 못한 곳이 없다면 1단계로 돌아간다.만약 네 방향 모두 가본 칸이거나 바다로 되어 있는 칸이면, 바라보는 방향을 유지한 채로 한 칸 뒤로 가고 1단계로 돌아간다.뒤쪽 방향이 바다라면 움직임을 멈춘다.메뉴얼에 따라 캐릭터를 이동시킨 뒤에 캐릭터가 방문한 칸의 수를 출력하라.
b. 입력 조건
첫째 줄에 맵의 세로 크기 N과 가로 크기 M을 공백으로 구분하여 입력한다
3 <= N, M <= 50
둘째 줄에 게임 캐릭터가 있는 칸의 좌표 (A, B)와 바라보는 방향 d가 각각 공백으로 구분하여 주어진다.방향 값은 다음과 같다.
0북쪽1동쪽2남쪽3서쪽
셋째 줄부터 맵이 육지인지 바다인지에 대한 정보가 주어진다.N개의 줄에 맵의 상태가 북쪽부터 남쪽 순서대로, 각 줄의 데이터는 서쪽부터 동쪽 순서대로 주어진다.맵의 외곽은 항상 바다이다.
맵 값은 다음과 같다0육지1바다처음에 게임 캐릭터가 위치한 칸의 상태는 항상 육지이다.
c. 출력 조건
첫째 줄에 이동을 마친 후 캐릭터가 방문한 칸의 수를 출력한다.
더보기
# N, M을 공백을 기준으로 구분하여 입력받기
n, m = map(int, input().split())
# 방문한 위치를 저장하기 위한 맵을 생성하여 0으로 초기화
d = [[0] * m for _ in range(n)]
# 현재 캐릭터의 X 좌표, Y 좌표, 방향을 입력받기
x, y, direction = map(int, input().split())
d[x][y] = 1 # 현재 좌표 방문 처리
# 전체 맵 정보를 입력받기
array = []
for i in range(n):
array.append(list(map(int, input().split())))
# 북, 동, 남, 서 방향 정의
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
# 왼쪽으로 회전
def turn_left():
global direction
direction -= 1
if direction == -1:
direction = 3
# 시뮬레이션 시작
count = 1
turn_time = 0
while True:
# 왼쪽으로 회전
turn_left()
nx = x + dx[direction]
ny = y + dy[direction]
# 회전한 이후 정면에 가보지 않은 칸이 존재하는 경우 이동
if d[nx][ny] == 0 and array[nx][ny] == 0:
d[nx][ny] = 1
x = nx
y = ny
count += 1
turn_time = 0
continue
# 회전한 이후 정면에 가보지 않은 칸이 없거나 바다인 경우
else:
turn_time += 1
# 네 방향 모두 갈 수 없는 경우
if turn_time == 4:
nx = x - dx[direction]
ny = y - dy[direction]
# 뒤로 갈 수 있다면 이동하기
if array[nx][ny] == 0:
x = nx
y = ny
# 뒤가 바다로 막혀있는 경우
else:
break
turn_time = 0
# 정답 출력
print(count)
럭키 스트레이
더보기
n = input()
length = len(n) # 점수 값의 총 자릿수
summary = 0
# 왼쪽 부분의 자릿수의 합 더하기
for i in range(length // 2):
summary += int(n[i])
# 오른쪽 부분의 자릿수의 합 빼기
for i in range(length // 2, length):
summary -= int(n[i])
# 왼쪽 부분과 오른쪽 부분의 자릿수 합이 동일한지 검사
if summary == 0:
print("LUCKY")
else:
print("READY")
문자열 재정렬
A. 문제
알파벳 대문자와 숫자(0~9)로만 구성된 문자열이 입력으로 주어진다. 모든 알파벳을 오름차순으로 정렬하여 출력하고, 모든 숫자를 더한 값을 이어서 출력한다.
a. 예를 들면.
K1KA5CB7은 AB CKK13이다.
b. 입력 조건
첫째 줄에 하나의 문자열 S가 주어진다1 <= S의 길이 <= 10000
c. 출력 조건
문제에서 요구하는 정답을 출력
더보기
data = input()
result = []
value = 0
# 문자를 하나씩 확인하며
for x in data:
# 알파벳인 경우 결과 리스트에 삽입
if x.isalpha():
result.append(x)
# 숫자는 따로 더하기
else:
value += int(x)
# 알파벳을 오름차순으로 정렬
result.sort()
# 숫자가 하나라도 존재하는 경우 가장 뒤에 삽입
if value != 0:
result.append(str(value))
# 최종 결과 출력(리스트를 문자열로 변환하여 출력)
print(''.join(result))
문자열 압축
더보기
def solution(s):
answer = len(s)
# 1개 단위(step)부터 압축 단위를 늘려가며 확인
for step in range(1, len(s) // 2 + 1):
compressed = ""
prev = s[0:step] # 앞에서부터 step만큼의 문자열 추출
count = 1
# 단위(step) 크기만큼 증가시키며 이전 문자열과 비교
for j in range(step, len(s), step):
# 이전 상태와 동일하다면 압축 횟수(count) 증가
if prev == s[j:j + step]:
count += 1
# 다른 문자열이 나왔다면(더 이상 압축하지 못하는 경우라면)
else:
compressed += str(count) + prev if count >= 2 else prev
prev = s[j:j + step] # 다시 상태 초기화
count = 1
# 남아있는 문자열에 대해서 처리
compressed += str(count) + prev if count >= 2 else prev
# 만들어지는 압축 문자열이 가장 짧은 것이 정답
answer = min(answer, len(compressed))
return answer
자물쇠와 열쇠
더보기
# 2차원 리스트 90도 회전하기
def rotate_a_matrix_by_90_degree(a):
n = len(a) # 행 길이 계산
m = len(a[0]) # 열 길이 계산
result = [[0] * n for _ in range(m)] # 결과 리스트
for i in range(n):
for j in range(m):
result[j][n - i - 1] = a[i][j]
return result
# 자물쇠의 중간 부분이 모두 1인지 확인
def check(new_lock):
lock_length = len(new_lock) // 3
for i in range(lock_length, lock_length * 2):
for j in range(lock_length, lock_length * 2):
if new_lock[i][j] != 1:
return False
return True
def solution(key, lock):
n = len(lock)
m = len(key)
# 자물쇠의 크기를 기존의 3배로 변환
new_lock = [[0] * (n * 3) for _ in range(n * 3)]
# 새로운 자물쇠의 중앙 부분에 기존의 자물쇠 넣기
for i in range(n):
for j in range(n):
new_lock[i + n][j + n] = lock[i][j]
# 4가지 방향에 대해서 확인
for rotation in range(4):
key = rotate_a_matrix_by_90_degree(key) # 열쇠 회전
for x in range(n * 2):
for y in range(n * 2):
# 자물쇠에 열쇠를 끼워 넣기
for i in range(m):
for j in range(m):
new_lock[x + i][y + j] += key[i][j]
# 새로운 자물쇠에 열쇠가 정확히 들어 맞는지 검사
if check(new_lock) == True:
return True
# 자물쇠에서 열쇠를 다시 빼기
for i in range(m):
for j in range(m):
new_lock[x + i][y + j] -= key[i][j]
return False
뱀
더보기
n = int(input())
k = int(input())
data = [[0] * (n + 1) for _ in range(n + 1)] # 맵 정보
info = [] # 방향 회전 정보
# 맵 정보(사과 있는 곳은 1로 표시)
for _ in range(k):
a, b = map(int, input().split())
data[a][b] = 1
# 방향 회전 정보 입력
l = int(input())
for _ in range(l):
x, c = input().split()
info.append((int(x), c))
# 처음에는 오른쪽을 보고 있으므로(동, 남, 서, 북)
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def turn(direction, c):
if c == "L":
direction = (direction - 1) % 4
else:
direction = (direction + 1) % 4
return direction
def simulate():
x, y = 1, 1 # 뱀의 머리 위치
data[x][y] = 2 # 뱀이 존재하는 위치는 2로 표시
direction = 0 # 처음에는 동쪽을 보고 있음
time = 0 # 시작한 뒤에 지난 '초' 시간
index = 0 # 다음에 회전할 정보
q = [(x, y)] # 뱀이 차지하고 있는 위치 정보(꼬리가 앞쪽)
while True:
nx = x + dx[direction]
ny = y + dy[direction]
# 맵 범위 안에 있고, 뱀의 몸통이 없는 위치라면
if 1 <= nx and nx <= n and 1 <= ny and ny <= n and data[nx][ny] != 2:
# 사과가 없다면 이동 후에 꼬리 제거
if data[nx][ny] == 0:
data[nx][ny] = 2
q.append((nx, ny))
px, py = q.pop(0)
data[px][py] = 0
# 사과가 있다면 이동 후에 꼬리 그대로 두기
if data[nx][ny] == 1:
data[nx][ny] = 2
q.append((nx, ny))
# 벽이나 뱀의 몸통과 부딪혔다면
else:
time += 1
break
x, y = nx, ny # 다음 위치로 머리를 이동
time += 1
if index < l and time == info[index][0]: # 회전할 시간인 경우 회전
direction = turn(direction, info[index][1])
index += 1
return time
print(simulate())
기둥과 보 설치
더보기
# 현재 설치된 구조물이 '가능한' 구조물인지 확인하는 함수
def possible(answer):
for x, y, stuff in answer:
if stuff == 0: # 설치된 것이 '기둥'인 경우
# '바닥 위' 혹은 '보의 한쪽 끝 부분 위' 혹은 '다른 기둥 위'라면 정상
if y == 0 or [x - 1, y, 1] in answer or [x, y, 1] in answer or [x, y - 1, 0] in answer:
continue
return False # 아니라면 거짓(False) 반환
elif stuff == 1: # 설치된 것이 '보'인 경우
# '한쪽 끝부분이 기둥 위' 혹은 '양쪽 끝부분이 다른 보와 동시에 연결'이라면 정상
if [x, y - 1, 0] in answer or [x + 1, y - 1, 0] in answer or ([x - 1, y, 1] in answer and [x + 1, y, 1] in answer):
continue
return False # 아니라면 거짓(False) 반환
return True
def solution(n, build_frame):
answer = []
for frame in build_frame: # 작업(frame)의 개수는 최대 1,000개
x, y, stuff, operate = frame
if operate == 0: # 삭제하는 경우
answer.remove([x, y, stuff]) # 일단 삭제를 해본 뒤에
if not possible(answer): # 가능한 구조물인지 확인
answer.append([x, y, stuff]) # 가능한 구조물이 아니라면 다시 설치
if operate == 1: # 설치하는 경우
answer.append([x, y, stuff]) # 일단 설치를 해본 뒤에
if not possible(answer): # 가능한 구조물인지 확인
answer.remove([x, y, stuff]) # 가능한 구조물이 아니라면 다시 제거
return sorted(answer) # 정렬된 결과를 반환
치킨 배달
더보기
from itertools import combinations
n, m = map(int, input().split())
chicken, house = [], []
for r in range(n):
data = list(map(int, input().split()))
for c in range(n):
if data[c] == 1:
house.append((r, c)) # 일반 집
elif data[c] == 2:
chicken.append((r, c)) # 치킨집
# 모든 치킨 집 중에서 m개의 치킨 집을 뽑는 조합 계산
candidates = list(combinations(chicken, m))
# 치킨 거리의 합을 계산하는 함수
def get_sum(candidate):
result = 0
# 모든 집에 대하여
for hx, hy in house:
# 가장 가까운 치킨 집을 찾기
temp = 1e9
for cx, cy in candidate:
temp = min(temp, abs(hx - cx) + abs(hy - cy))
# 가장 가까운 치킨 집까지의 거리를 더하기
result += temp
# 치킨 거리의 합 반환
return result
# 치킨 거리의 합의 최소를 찾아 출력
result = 1e9
for candidate in candidates:
result = min(result, get_sum(candidate))
print(result)
외벽점검
더보기
from itertools import permutations
def solution(n, weak, dist):
# 길이를 2배로 늘려서 '원형'을 일자 형태로 변형
length = len(weak)
for i in range(length):
weak.append(weak[i] + n)
answer = len(dist) + 1 # 투입할 친구 수의 최솟값을 찾아야 하므로 len(dist) + 1로 초기화
# 0부터 length - 1까지의 위치를 각각 시작점으로 설정
for start in range(length):
# 친구를 나열하는 모든 경우 각각에 대하여 확인
for friends in list(permutations(dist, len(dist))):
count = 1 # 투입할 친구의 수
# 해당 친구가 점검할 수 있는 마지막 위치
position = weak[start] + friends[count - 1]
# 시작점부터 모든 취약한 지점을 확인
for index in range(start, start + length):
# 점검할 수 있는 위치를 벗어나는 경우
if position < weak[index]:
count += 1 # 새로운 친구를 투입
if count > len(dist): # 더 투입이 불가능하다면 종료
break
position = weak[index] + friends[count - 1]
answer = min(answer, count) # 최솟값 계산
if answer > len(dist):
return -1
return answer
'프로그래밍 > 알고리즘' 카테고리의 다른 글
이코테 정렬 파이썬 (0) | 2023.02.12 |
---|---|
이코테 DFS/BFS 파이썬 (0) | 2023.02.12 |
이코테 그리디 파이썬 (0) | 2023.02.12 |
백준 - N과 M(1) 15649번 파이썬 (3) | 2023.02.10 |
백준 - 1로 만들기 1463 파이썬 (0) | 2023.02.09 |
댓글