拼多多:选靓号(Python语言实现)

题目描述

A国的手机号码由且仅由N位十进制数字(0-9)组成。一个手机号码中有至少K位数字相同则被定义为靓号。
A国的手机号可以有前导零,比如000123456是一个合法的手机号。
小多想花钱将自己的手机号码修改为一个靓号。修改号码中的一个数字需要花费的金额为新数字与旧数字之间的差值。
比如将1修改为6或6修改为1都需要花5块钱。
给出小多现在的手机号码,问将其修改成一个靓号,最少需要多少钱?
  • 输入描述
第一行包含2个整数N、K,分别表示手机号码数字个数以及靓号至少有K个数字相同。
第二行包含N个字符,每个字符都是一个数字('0'-'9'),数字之间没有任何其他空白符。表示小多的手机号码。
数据范围:2 <= K <= N <= 10000
  • 输出描述
第一行包含一个整数,表示修改成一个靓号,最少需要的金额。
第二行包含N个数字字符,表示最少花费修改的新手机号。若有多个靓号花费都最少,则输出字典序最小的靓号。
  • 示例
输入:
6 5
787585

输出:
4
777577

找规律

最少花费通过设置上下界依次对求每个数字修改的差值的和进行求得。进行值修改的时候要注意,大于的要从前往后,小于的要从后往前,这样输出的总是字典序最小的。

def select_phone_number(seq, k):
    front, rear = min(seq), max(seq)
    value, compare = 0, float('inf')
    for cur in range(front, rear+1):
        subtraction = [abs(cur-su) for su in seq]
        traction = sorted(subtraction)
        current = sum(traction[:k])
        if current < compare:
            compare = current
            value = cur
    pos = [value-su for su in seq]
    stand = sorted(list(set(map(lambda x: abs(x), pos))))
    while k > 0:
        nxt = min(stand)
        if nxt == 0:
            k -= pos.count(0)
            stand.remove(nxt)
            continue
        left = value + nxt
        while k > 0 and left in seq:
            li = seq.index(left)
            seq[li] = value
            k -= 1
        right = value - nxt
        while k > 0 and right in seq:
            ri = len(seq)-1-(seq[::-1].index(right))
            seq[ri] = value
            k -= 1
        stand.remove(nxt)
    return compare, seq


if __name__ == '__main__':
    [n, k] = list(map(int, input().strip().split()))
    seq = list(map(int, list(input().strip())))
    value, res = select_phone_number(seq, k)
    print(value)
    print(''.join(map(lambda ru: str(ru), res)))

(最近更新:2019年09月01日)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值