[BOJ][Python] 백준 27450 번: 플래그 대사 그만 좀 말해요
1일 1PS 72일차!
📚 문제
[골드 1] - 플래그 대사 그만 좀 말해요
💡 풀이 과정
- 간단하지만 헷갈리는 문제다.
- 딱히 알고리즘은 필요없지만 수상하게 난이도가 높은 피지컬 문제..?
- 우선 문제는 간단하다.
-
매번 목표 수치가 되도록 외침해주고 동시에 뒤에 부하까지 max(0, K-i) 만큼 더해주면 풀리지만 당연히 시간초과이다.
- 강화에 대해 로직을 살펴보면
- 1번에서 K= 3 으로 외친다면
- +3, +2, +1 로 강화된다.
- 3번을 외친다면
- +9, +6, +3 으로 강화된다.
- 위를 살펴보면 다음 부하로 이동하면서 외침의 횟수만큼 줄어들게 된다.
- 이는 거리가 멀어질수록 1칸당 1의 강함이 고정적으로 감소하기 때문이다!!
- 그렇다면 우리는 현재 위치에서 추가되는 강함의 수치에서 영향을 받은 총 외침의 수를 빼주기만하면 다음 위치에서 적용받는 강함의 수치를 바로 알 수 있다!
- i=2, k=3 에서 강함수치가 10 증가했고 이는 (0, 1, 2) 번째에서 총 4번의 외침으로 증가했다면
- i=3 에 도착하자마자 강화되는 수치는 10-4 라는 뜻이다.
- 여기서 다시 2번의 외침을 시전해서 총 12의 강화수치를 얻었다면 (0, 1, 2, 3) 에서 총 6번의 외침으로 12의 강함 수치를 얻었다는 것이다.
- 하지만 K=3 이기에 0번째 외침은 i=4 에 아무런 영향을 미치지 못하기에 총 외침 횟수에서 0번째 외침 횟수를 제해야한다.
📌포인트
- while 문을 사용해서 cnt 를 구했지만 시간초과의 요소이다.
- if else 문을 사용하고 // 연산자를 활용하도록 하자.
- 요소들을 연산하는 순서가 매우 중요하다.
- 특정 i, k 값에 대해서 원하는 동작을 주석으로 작성하면서 코딩하자.
💻 코드
N, K = map(int, input().split())
P = list(map(int, input().split()))
T = list(map(int, input().split()))
flags = [0] * N
# 총 외침 횟수
cnt_shout = 0
# 외침으로 추가 강함 수치
total_shout = 0
# 앞에서부터..
for i in range(N):
# 이전에 total_shout 를 추가해준다.
P[i] += total_shout
# 현재 단계에서 몇 번을 외쳐야 강해지는 가?
# cnt = 0
# while P[i] < T[i]:
# cnt += 1
# P[i] += K
cnt = 0 if P[i] >= T[i] else ((T[i] - P[i] - 1) // K) + 1
# 현재 위치에서 cnt 번 외쳐야한다.
flags[i] = cnt
# 외침 횟수
cnt_shout += cnt
# K 거리까지만 영향이 있으므로 멀리 떨어진 외침은 삭제
# K=3, i=3 일때 (1, 2, 3) 횟수를 가지고 있다.
if i > K - 1:
cnt_shout -= flags[i - K]
# 총 강함 수치 더해준다.
total_shout += cnt * K
# K=3, i=3 일때 다음 부하를 위해 cnt_shout 만큼 줄어들어야한다.
total_shout -= cnt_shout
print(sum(flags))
댓글남기기