2024牛客五一集训派对day2:The Crime-solving Plan of Groundhog(含证明)

2024牛客五一集训派对day2:The Crime-solving Plan of Groundhog(含证明)

https://ac.nowcoder.com/acm/contest/80998/I

题目大意:

给定 n n n 个0~9的整数,用这些数码拼凑出 2 2 2 个整数,求所有可能的最小乘积

思路:

一个因数是:最小的非零数(如果有多个,只取其中一个)

另一个因数:删除选走的那个,剩下的非零数从小到大排序,然后所有0插在第一个数后面

因为涉及到高精度,所以用Python(懒得写高精度bushi

正确性证明

先不考虑数码中包含0的情况,假设所有数码都属于1~9,研究这个子问题:

  • 引理1:如果 A A A , B B B 分配的数码都已经确定,那么如果想最小化乘积,就要使A,B的所有数码升序排列。(这个太显然就不证明了)

  • 引理2:如果 A A A 只选 1 1 1 个数码, B B B ( n − 1 ) (n-1) (n1) 个数码,(根据引理 1 1 1 B B B 升序排列),这种情况下, A A A 选择最小的数能使得 A A A B B B 乘积最小

    证明:(形式化的就不写了,一图胜千言)

    在这里插入图片描述

  • 如果不限制“ 1 1 1 个因数 1 1 1 个数码,另一个因数 ( n − 1 ) (n-1) (n1) 个数码”,而也考虑到其他情况,比如“一个因数分配 2 2 2 个数码,另一个因数分配 ( n − 2 ) (n-2) (n2) 个数码” ,会不会答案就不是我们这个了呢

    答:不会,还是用图证明:

    在这里插入图片描述

    考虑给定数码中有0的情况

    对于每一个 0 0 0

    如果给 B B B ,那么一定是插在第一个数字后面,否则只会更大

    那么如果插 A A A 后面呢?

    在这里插入图片描述

AC code:

def solve():
    for i in range(t):
        n = int(input())
        a = input().split()
        a.sort()
        i = 0
        while a[i] == '0':
            i += 1
        x = a[i]
        y = a[i + 1] + '0' * i + "".join(a[i + 2:])
        print(int(x) * int(y))


t = int(input())
for i in range(t):
    solve()
  • 27
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值