coding test

[파이썬] 4831. 전기버스

잔망루피 2021. 1. 4. 16:28

swexpertacademy.com/main/learn/course/lectureProblemViewer.do

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

A도시는 전기버스를 운행하려고 한다. 전기버스는 한번 충전으로 이동할 수 있는 정류장 수가 정해져 있어서, 중간에 충전기가 설치된 정류장을 만들기로 했다.

버스는 0번에서 출발해 종점인 N번 정류장까지 이동하고, 한번 충전으로 최대한 이동할 수 있는 정류장 수 K가 정해져 있다.

충전기가 설치된 M개의 정류장 번호가 주어질 때, 최소한 몇 번의 충전을 해야 종점에 도착할 수 있는지 출력하는 프로그램을 만드시오.

만약 충전기 설치가 잘못되어 종점에 도착할 수 없는 경우는 0을 출력한다. 출발지에는 항상 충전기가 설치되어 있지만 충전횟수에는 포함하지 않는다.


[예시]



다음은 K = 3, N = 10, M = 5, 충전기가 설치된 정류장이 1, 3, 5, 7, 9인 경우의 예이다.

 

[입력]
 

첫 줄에 노선 수 T가 주어진다.  ( 1 ≤ T ≤ 50 )


각 노선별로 K, N, M이 주어지고, 다음줄에 M개의 정류장 번호가 주어진다. ( 1 ≤ K, N, M  100 )
 

[출력]


#과 노선번호, 빈칸에 이어 최소 충전횟수 또는 0을 출력한다.

 

입력 출력
3
3 10 5
1 3 5 7 9
3 10 5
1 3 7 8 9
5 20 5
4 7 9 14 17
#1 3
#2 0
#3 4

 

🎃 모르겠는 것

1. 반복문을 어떻게 짜지? 시작을 못하겠다.

 

👑 다른사람 풀이

 

T=int(input())
for test_case in range(1, T+1):
    K, N, M = map(int,input().split())    # K=최대이동횟수, N=정류장, M=충전기
    charge = list(map(int, input().split()))  # 충전기
    station_lst=[0]*(N+1)					# 정류장(출발점0 포함)
    
    for i in range(len(charge)):
        station_lst[charge[i]]+=1		# 정류장 station_lst에서 충전기가 있는 곳만 1로 초기화
        
    start=0		# start와 end는 이동거리
    end=K
    cnt=0    #충전횟수
    
    while True:
        zero=0
        for i in range(start+1, end+1):
            if station_lst[i] == 1: 		# 주유소에 도착하면
                start=i							# 시작점을 주요소가 있는 위치로 
            else:
                zero+=1
        if zero == K:				# 종점에 도착을 못해
            cnt=0
            break
            
        cnt+=1
        end=start+K
        
        if end >= N:		# 도착하면
            break
    print('#%s %d' %(test_case, cnt))

 

코드가 길뿐 쉽네;;

정류장 station_lst는 0부터 시작하므로 길이를 N+1만큼 해준다. 

for문으로 정류장 station_lst charge[i]인덱스에 1을 초기화한다.

while문내의 for문은 최대이동거리만큼 반복한다.

station_lst[i]가 1이면 주유소에 도착한 것이다. start를 이 위치로 초기화한다.

그렇지 않으면 zero를 1증가시킨다. zero가 K랑 같으면 충전기 설치가 잘못되어 종점에 도착할 수 없는 경우이다.

end는 start+k로 늘어난다.

end가 N보다 크거나 같으면 도착한것이므로 while문을 break한다.

 

import sys
sys.stdin = open("inputs/bus_input.txt")
def solution(K, N, stops):
    """
    :param K: 한번 충전시 갈 수 있는 정류장 수
    :param N: 종점까지 정류장 갯수
    :param stops: 충전기가 설치된 정류장 목록 (번호로 주어짐)
    :return: 최소한의 충전 횟수
    SW Expert Academy 4831. 전기 버스(d3) / 시간복잡도 : O(n) 예상
    """
    answer = prev = 0
    # answer는 최종 정답, prev는 현재 정거장과 다음 정거장의 거리를 계산하기 위해 사용
    status = K
    # status는 현재 충전 현황을 뜻함
    for i in range(len(stops) - 1):
        status -= stops[i] - prev
        # 그 다음 충전기가 있는 정류장까지 갔으므로 충전 현황을 계산
        if status < 0:
            return 0 # 만약 0보다 작다면 충전량으로 현재 정류소까지 갈 수 없으므로 0 반환
        if stops[i + 1] - stops[i] > status:	# 다음 정류장까지의 거리를 계산 후 status와 비교
            status = K
            answer += 1
        """
        핵심로직!
        우리의 관심사는 충전소가 있는 정류장마다 충전하는 것이 아니다!
        충전 횟수를 최소화해야하므로 그다음 현재 가지고 있는 충전량으로 그다음 충전소까지
        갈 수 있는지 계산하여 충전하도록 만듦
        """
        prev = stops[i] # 이전 정류소 갱신
    # for문에서 마지막 정류소를 계산하지 않았으므로 마지막 정류소까지 계산
    last = stops[-1]
    status -= last - prev
    if N - last > K:		# 도착할 수 없다
        return 0
    elif N - last > status:
        answer += 1
    return answer

def main():
    T = int(input())
    for test_case in range(T):
        K, N, M = map(int, input().split())
        stops = list(map(int, input().split()))
        print(f"#{test_case + 1} {solution(K, N, stops)}")

if __name__ == '__main__':
    main()

 

for문의 범위를 len(stops)-1로 해야 if stops[i+1]-stops[i]>status에서 index 에러가 안난다.

status는 충전소 stops[i]에서 이전 정거장 prev를 뺀 값을 뺀다. status를 연료로 생각하기.

status가 음수가 되면 0을 return한다.

현재 충전소와 그 다음 충전소의 거리를 계산하고 status와 비교한다. status가 더 작으면 충전이 필요하다. status는 K로 만땅 채우고 충전 횟수 answer이 1 증가한다.

한 번 충전 시 갈 수 있는 정류장 수 K보다 크면 return 0을 한다.

prev에 stops[i]를 넣어준다.

for문이 끝나면 마지막 충전소에 대해 계산한다.

마지막 충천소가 최대 이동거리 K보다 더 멀리 떨어져 있다면 return 0

그렇지 않고 정류장 거리 N-마지막 충전소 last가 연료 status보다 크면 충전횟수를 늘린다.

 

👠 느낀점

나도 2번 코드처럼 충전소의 거리만으로 계산하고 싶었는데,,ㅋㅋ

연료 status와 이전 충전소 prev가 있어야 했다.

 

 

반응형

'coding test' 카테고리의 다른 글

[파이썬] 4835. 구간합  (0) 2021.01.06
[파이썬] 4834. 숫자 카드  (0) 2021.01.05
[파이썬] 풍선 터트리기  (0) 2021.01.04
[파이썬] 조이스틱  (0) 2020.12.31
[파이썬, Java] 다리를 지나는 트럭  (0) 2020.12.28