踩的坑
递归函数不能是local的
超级麻烦一题,混合了Dijkstra和深度优先搜索,写到这里想起来两遍Dijkstra好像也可以,性能会好一点,考试时有这种题真的来得及吗…
基本上稍微带点暴力算法在pta里都行不通不要再撞大运式编程了
代码
--IO
local read_io = io.read('*a'):gmatch('%w+')
local read_func = function()
return tonumber(read_io())
end
--para
local Cmax = read_func() Ns = read_func() Sp = read_func() Nr = read_func()
local Cperfect = Cmax / 2
local roads = {}
--{station1 = x, station2 = x, time = x}
local stations = {}
--{current_bike = x, require_bike = x, avalible_stations = {}, time = x}
local ptrs = {}
local collect = nil send = nil
local temp_collect = 0 temp_send = 0
local path = {}
--logic
local tryRecordPtrs = function(index)
for _, v in pairs(ptrs) do
if v == index then
return
end
end
table.insert(ptrs, index)
end
local tryUpdateStation = function(from_index, target_index, time)
local from_station = stations[from_index]
local target_station = stations[target_index]
if not target_station.time or from_station.time + time < target_station.time then
target_station.avalible_stations = {from_index}
target_station.time = from_station.time + time
tryRecordPtrs(target_index)
elseif from_station.time + time == target_station.time then
table.insert(target_station.avalible_stations, from_index)
end
end
calculatePath = function(index)
if index == 0 then
if (not send or not collect) or (temp_send < send) or (temp_send == send and temp_collect < collect) then
send = temp_send
collect = temp_collect
path = {}
for _, station_index in pairs(ptrs) do
table.insert(path, station_index)
end
end
else
table.insert(ptrs, 1, index)
local record_collect = temp_collect record_send = temp_send
local station = stations[index]
if station.require_bike > 0 then
temp_send = temp_send + station.require_bike
else
if - station.require_bike > temp_send then
temp_collect = temp_collect - station.require_bike - temp_send
temp_send = 0
else
temp_send = temp_send + station.require_bike
end
end
for _, next_index in pairs(stations[index].avalible_stations) do
calculatePath(next_index)
end
table.remove(ptrs, 1)
temp_collect = record_collect
temp_send = record_send
end
end
local generateResult = function()
local result = ""
result = result .. tostring(send) .. " "
result = result .. "0"
for _, index in pairs(path) do
result = result .. "->" .. tostring(index)
end
result = result .. " " .. tostring(collect)
return result
end
--main
for index = 1, Ns do
local station = {current_bike = read_func()}
station.require_bike = Cperfect - station.current_bike
table.insert(stations, station)
end
stations[0] = {time = 0}
for index = 1, Nr do
local road = {station1 = read_func(), station2 = read_func(), time = read_func()}
table.insert(roads, road)
end
table.insert(ptrs, 0)
local sort_function = function(a, b)
return stations[a].time < stations[b].time
end
while #ptrs > 0 do
ptr = table.remove(ptrs, 1)
for _, road in pairs(roads) do
if road.station1 == ptr then
tryUpdateStation(road.station1, road.station2, road.time)
elseif road.station2 == ptr then
tryUpdateStation(road.station2, road.station1, road.time)
end
end
table.sort(ptrs, sort_function)
end
calculatePath(Sp)
local result = generateResult()
print(result)