문제집(1766번) 이후로 이런 일은 없을 줄 알았는데... 정해를 무시하고 내 방식대로 하겠다고 깝치다가 틀리거나 시간초과를 받은 게 너무 많아서 66번의 제출 끝에 맞았습니다!! 를 받았다.
(참고로, 정해 무시하고 내 방식대로 계속 코드 제출하다가 맞은 건 색종이 붙이기라는 문제 뿐이고, 이마저도 그냥 백트래킹만 한 게 아니라 경로 저장까지 해서 중복되는 경우를 없애서 확실히 맞을 거 같은 코드는 시간초과가 났고, 그 코드에서 함수 호출 횟수를 재서 특정 값을 초과하면 그냥 지금까지 계산한 결과를 반환하는 코드를 냈더니 932ms로 간신히 통과했다. 답에 해당하는 경우는 빨리 나오는데 모든 경우의 수를 다 계산하려면 많은 시간이 걸리는 문제였던 것으로 추정된다.
모든 경우의 수를 세려면 함수를 191836번 호출해야 하던 테스트 케이스도 실제로는 답이 15번만에 나왔었다.)
우선순위큐를 안 쓰고 정렬로만 하려다 시간초과가 나다가...
일단 가지고 있는 연료를 다 써서 현재 위치를 바꾼 다음 이동한 범위 내에 있는 주유소들 중에서 연료를 채우고,
그렇게 해서 다음 주유소까지 가도록 하는 코드를 짰으나...
6
1 3
2 3
3 3
4 3
5 1
17 3
20 4
이 반례 (내가 만들었고, 정해는 6이다.) 에서 문제가 생겼다. 모든 주유소에서 기름을 채워야 목적지에 도달할 수 있는데,
5번 주유소에 가려면 주유소 1~4에서 기름을 한 번만 채워도 되기에 기름을 한 번만 채웠고, 5번 주유소에서 6번 주유소에 갈 수 없어서 -1을 출력했던 것이다.
그래서 기준(코드에서는 변수 nextoil) 을 다음 주유소로 설정하고, 경우를 나눠서 nextoil을 어느 주유소로 할 지 구분하는 코드를 짜다가 엄청나게 많은 틀렸습니다를 받았고,
결국 다른 사람이 이 문제를 푼 로직만 읽고 구현을 해서 맞았습니다를 받았다.
(원래는 코드를 읽고 원리를 이해한 다음 코드를 그대로 다른 언어로 구현했는데, 소형기관차 문제를 시작으로 로직만 읽고 코드는 안 읽고 구현하는 게 가능해졌다.)
n=io.read("*n")
local dist,cnt
dist,cnt=0,0
oil={}
for i=1,n do a,b=io.read("*n","*n") oil[a]=b end
local l,p
l,p=io.read("*n","*n") --p:남은 연료량
oil[l]=0
queue={}
function inserting(idx)
local j
j=#queue+1
queue[j]=idx
while j>1 do
if queue[j]>queue[j//2] then
queue[j],queue[j//2]=queue[j//2],queue[j]
j=j//2
else
break
end
end
end
function del()
local point,ans=1,1
if #queue>1 then
ans,queue[1]=queue[1],table.remove(queue)
while queue[point] do
local a,b=queue[point*2],queue[point*2+1]
if not a then break
elseif not b then c=point*2
elseif a>b then c=point*2
elseif b then c=point*2+1
else break
end
if queue[point]<queue[c] then
queue[point],queue[c]=queue[c],queue[point]
point=c
else break
end
end
else ans=table.remove(queue)
end
return ans
end
while dist<l do
nextoil=l
for i=dist+1,l do if oil[i]~=nil and nextoil==l then nextoil=i break end end
for i=dist,dist+p do if oil[i]~=nil and oil[i]~=0 then inserting(oil[i]) oil[i]=nil end end
while dist+p<nextoil and #queue>0 do
p=p+del()
cnt=cnt+1
end
p=p-nextoil+dist
if p<0 then io.write(-1) os.exit() end
dist=nextoil
if dist>=l then io.write(cnt) os.exit() end
if #queue==0 and dist+p<nextoil then io.write(-1) os.exit() end
end
(왜 티스토리 코드블럭에는 Lua랑 Rust가 없을까...?)
처음에는 dist값에다가 현재 연료량인 p값을 더하고 p를 0으로 만들었다가 nextoil(다음 주유소) 에서 채울 수 있는 만큼의 연료를 p값에 다시 할당하는 방식이었는데, 나중에는 nextoil을 dist,dist+p 사이에 있는 값으로 하고 nextoil과 dist의 차이를 p에서 빼주는 방식으로 했다. 후자만 맞았습니다!!! 를 받았다.
'코딩 > Lua' 카테고리의 다른 글
[Lua] 백준 19566 수열의 구간 평균 (1) | 2024.01.22 |
---|---|
[Lua] 백준 25419 정수를 끝까지 외치자 (0) | 2023.12.14 |
[Lua] 백준 13913 숨바꼭질 4 (0) | 2023.02.26 |
[Lua] 백준 27440 1로 만들기 3 (0) | 2023.02.19 |
[Lua] 백준 2003 수들의 합 2 (0) | 2023.01.07 |