2021. 11. 23. 01:18ㆍ알고리즘/그리디
문제
백준이는 한 작은 회사에 취직했다. 이 회사에서 백준이는 소스 코드의 뒤죽박죽인 인덴트를 고치고 있다. 인덴트는 각 줄을 탭 키를 이용해 들여 쓰는 것을 말한다. 다행히 백준이가 사용하는 편집기는 연속된 줄을 그룹으로 선택하고, 여기에서 각 줄의 앞에 탭을 추가하거나, 삭제할 수 있다. 백준이를 도와 코드의 뒤죽박죽인 인덴트를 예쁘게 고치는 방법을 생각해보자.
줄의 개수 N과 각 줄의 앞에 있는 탭의 개수와 올바른 탭의 개수가 주어진다. 이때, 한 번 편집을 할 때, 다음과 같은 명령을 수행할 수 있다.
- 연속된 줄을 그룹으로 선택한다.
- 선택된 줄의 앞에 탭 1개를 추가하거나 삭제한다.
위의 두 명령을 모두 수행하는 것이 하나의 편집이며, 선택된 줄의 개수와는 상관이 없다. 만약, 선택한 줄 중에 단 한 줄이라도 탭이 없을 경우에는, 탭을 삭제하는 명령을 수행할 수 없다.
백준이가 몇 번 편집 만에 코드의 인덴트를 올바르게 고칠 수 있는지 구하는 프로그램을 작성하시오. 이때, 편집 회수의 최솟값을 구해야 한다.
입력
첫째 줄에 줄의 개수 N(1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄에는 현재 줄에 있는 탭의 개수가 주어지며, 1번째 줄부터 순서대로 주어진다. 탭의 개수는 0보다 크거나 같고, 80보다 작거나 같은 정수이다. 셋째 줄에는 각 줄의 올바른 탭의 개수가 주어진다. 1번째 줄부터 순서대로 주어지며, 이 값도 0보다 크거나 같고, 80보다 작거나 같은 정수이다.
출력
첫째 줄에 코드의 인덴트를 올바르게 고치는 편집 회수의 최솟값을 출력한다.
예제 입력 1
3 3 4 5 6 7 8
예제 출력 1
3
예제 입력 2
4 1 2 3 4 3 1 1 0
예제 출력 2
6
예제 입력 3
4 5 4 5 5 1 5 0 1
예제 출력 3
10
접근 방법
- 현재 줄에 있는 탭과 올바른 탭을 비교하며 현재 상태에 따라 편집횟수를 저장한다.
- 1. 증가상태나 삭제상태에서 현재 줄에 있는 탭의 개수와 올바른 탭의 개수가 같다면 패스 상태(0)로 변환 후 패스한다.
- 2. 여태 바꾸지 않았거나 증가상태라면 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 크다면 개수를 하나 줄이고, 편집횟수를 하나 늘린다음 삭제 상태(1)로 변경한다.
- 2-1. 삭제 상태에서 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 크다면 개수를 하나 줄이고 패스한다.
- 3.여태 바꾸지 않았거나 삭제상태라면 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 작다면 개수를 하나 늘리고, 편집횟수를 하나 늘린다음 증가 상태(2)로 변경한다.
- 3-1. 증가 상태에서 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 작다면 개수를 하나 늘리고 패스한다.
- 모든 탐색이 끝나면 편집 횟수를 출력하고 종료한다.
코드
# https://www.acmicpc.net/problem/2879
# 접근방법
# 현재 줄에 있는 탭과 올바른 탭을 비교하며 현재 상태에 따라 편집횟수를 저장한다.
# 1. 증가상태나 삭제상태에서 현재 줄에 있는 탭의 개수와 올바른 탭의 개수가 같다면 패스 상태(0)로 변환 후 패스한다.
# 2. 여태 바꾸지 않았거나 증가상태라면 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 크다면 개수를 하나 줄이고, 편집횟수를 하나 늘린다음 삭제 상태(1)로 변경한다.
# 2-1. 삭제 상태에서 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 크다면 개수를 하나 줄이고 패스한다.
# 3.여태 바꾸지 않았거나 삭제상태라면 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 작다면 개수를 하나 늘리고, 편집횟수를 하나 늘린다음 증가 상태(2)로 변경한다.
# 3-1. 증가 상태에서 현재 줄에 있는 탭의 개수가 올바른 탭의 개수보다 작다면 개수를 하나 늘리고 패스한다.
# 모든 탐색이 끝나면 편집 횟수를 출력하고 종료한다.
n = int(input())
now_tab = list(map(int, input().split()))
correct_tab = list(map(int, input().split()))
count = 0
condition = [0, 1, 2]
check = 0
while now_tab != correct_tab:
for i in range(n):
if now_tab[i] == correct_tab[i]:
check = 0
elif now_tab[i] > correct_tab[i]:
if check != 1:
count += 1
now_tab[i] -= 1
check = 1
else:
now_tab[i] -= 1
else:
if check != 2:
count += 1
now_tab[i] += 1
check = 2
else:
now_tab[i] += 1
check = 0
print(count)
'알고리즘 > 그리디' 카테고리의 다른 글
백준 온라인 저지, 그리디 / 4716번: 풍선 (파이썬 / , 백준 플레티넘문제) (0) | 2021.11.29 |
---|---|
백준 온라인 저지, 그리디 / 1781번: 컵라면 (파이썬 / , 백준 골드문제) (0) | 2021.11.29 |
백준 온라인 저지, 그리디 / 23254번: 나는기말고사형인간이야 (파이썬 / 백준 골드문제) (0) | 2021.11.23 |
백준 온라인 저지, 그리디 / 1041번: 주사위 (파이썬 / 백준 골드문제) (0) | 2021.11.22 |
백준 온라인 저지, 그리디 / 7983번: 내일할거야 (파이썬 / 백준 골드문제) (0) | 2021.11.22 |