用LUA刷PTA ——1016 Phone Bills

踩的坑

这题不难就是细节多比较烦人。
客户的名字会有数字!如果你跟我一样一个个数字的读就会炸裂!卡了好久!
推荐:学习C的读取方法,毕竟PTA最适配的语言还是C家族。

代码

--IO
local input = io.read('*a')
local read_string = string.gmatch(input,"%w+")

local read_number = function()
    return tonumber(read_string())
end

--parameter

local price = {} --24h
local records = {}
--{name = "xxx", month = x, day = x, hour = x, minute = x, is_online = bool}
local bills = {}
--{name = "xxx", month = x, record = {}, total_amount = x}
    --{start_time = "xx:xx:xx", end_time = "xx:xx:xx", duration = x, price = x}
local price_per_day = 0;

--logic

local formatNumber = function(para)
    return para < 10 and "0" .. para or para
end

local getPairedOffLineIndex = function(name)
    for index, record in pairs(records) do
        if record.name == name and record.is_online and index ~= 1 then
            return nil;
        end
        if record.name == name and not record.is_online then
            return index;
        end
    end
    return nil;
end

local getBill = function(name, month)
    for _, bill in pairs(bills) do
        if bill.name == name and bill.month == month then
            return bill;
        end
    end

    local bill = {
        name = name,
        month = month,
        record = {},
        total_amount = 0,
    }
    
    table.insert(bills, bill)
    return bill
end

local getDuration = function(online_record, offline_record)
    local duration = 0
    duration = duration + offline_record.day - online_record.day
    duration = duration * 24 + offline_record.hour - online_record.hour
    duration = duration * 60 + offline_record.minute - online_record.minute
    return duration
end

local getPriceInSameDay = function(start_hour, start_minute, end_hour, end_minute)
    if start_hour == end_hour then
        return price[start_hour + 1] * (end_minute - start_minute)
    end

    local result_price = price[start_hour + 1] * (60 - start_minute)
    start_hour = start_hour + 1
    result_price = result_price + price[end_hour + 1] * (end_minute)
    
    while start_hour < end_hour do
        result_price = result_price + price[start_hour + 1] * 60
        start_hour = start_hour + 1;
    end

    return result_price
    
end

local getPrice = function(online_record, offline_record)
    local result_price = 0
    local day = online_record.day
    
    while day < offline_record.day - 1 do
        result_price = result_price + price_per_day
        day = day + 1
    end
    
    if day == offline_record.day then
        result_price = result_price + getPriceInSameDay(online_record.hour, online_record.minute, offline_record.hour, offline_record.minute)
    else
        result_price = result_price + getPriceInSameDay(online_record.hour, online_record.minute, 23, 60)
        result_price = result_price + getPriceInSameDay(0, 0, offline_record.hour, offline_record.minute)
    end

    return result_price / 100
end

local processOneRecord = function()
    local online_record = records[1]
    if online_record.is_online then
        local off_line_index = getPairedOffLineIndex(online_record.name)
        if off_line_index then 
            offline_record = records[off_line_index]
            local bill = getBill(online_record.name, online_record.month)

            local bill_record = {
                start_time = formatNumber(online_record.day) .. ":" .. formatNumber(online_record.hour) .. ":" .. formatNumber(online_record.minute), 
                end_time = formatNumber(offline_record.day) .. ":" .. formatNumber(offline_record.hour) .. ":" .. formatNumber(offline_record.minute), 
                duration = getDuration(online_record, offline_record),
                price = getPrice(online_record, offline_record)
            }

            bill.total_amount = bill.total_amount + bill_record.price
            if bill_record.price ~= 0 then
                table.insert(bill.record, bill_record)
            end
            table.remove(records, off_line_index)
        end
    end
    table.remove(records, 1)
end

--main
for hour = 1, 24 do
    price[hour] = read_number()
    price_per_day = price_per_day + price[hour] * 60
end

local record_amount = read_number()

for _ = 1, record_amount do
    local record = {
        name = read_string(),
        month = read_number(), 
        day = read_number(), 
        hour = read_number(), 
        minute = read_number(),
        is_online = read_string() .. "-" .. read_string() == "on-line"
    }
    table.insert(records, record)
end

local chronologically_sort = function(a, b)
    return ((a.month * 100 + a.day) * 100 + a.hour) * 100 + a.minute < ((b.month * 100 + b.day) * 100 + b.hour) * 100 + b.minute
end

table.sort(records, chronologically_sort)

while #records > 0 do
    processOneRecord()
end

local alphabetical_sort = function(a, b)
    return a.name < b.name
end

table.sort(bills, alphabetical_sort)

for _, bill in pairs(bills) do
    if bill.total_amount ~= 0 then
        print(bill.name .. " " .. formatNumber(bill.month))
        for _, record in pairs(bill.record) do
            print(record.start_time .. " " .. record.end_time .. " " .. record.duration .. " " .. "$" .. string.format("%.2f", record.price))
        end
        print("Total amount: $" .. string.format("%.2f", bill.total_amount))
    end
end

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值