记录【CSDN竞赛第五期】的一道题:三而竭

【题目描述】

一鼓作气再而衰三而竭。

小艺总是喜欢把任务分开做。

小艺接到一个任务,任务的总任务量是 n n n

第一天小艺能完成 x x x 份任务。

第二天能完成 x k \frac{x}{k} kx

… …

t t t 天能完成 x k t − 1 \frac{x}{k^{t-1}} kt1x

小艺想知道自己第一天至少完成多少才能完成最后的任务。

【输入描述】

第一行输入整数 n n n k k k 。( 1 ≤ n ≤ 1 e 9 1 \leq n \leq 1e9 1n1e9 2 ≤ k ≤ 10 2 \leq k \leq 10 2k10

【输出描述】

输出 x x x 的最小值。

【输入样例】

59 9

【输出样例】

54

【代码模板】

编程语言:python3

# 请关闭中文输入法,用英文的字母和标点符号。
# 如果你想运行系统测试用例,请点击【执行代码】按钮,如果你想提交作答结果,请点击【提交】按钮,
# 注意:除答案外,请不要打印其他任何多余的字符,以免影响结果验证
# 本OJ系统是基于 OxCoder 技术开发,网址:www.oxcoder.com
# 模版代码提供基本的输入输出框架,可按个人代码习惯修改


class Solution:
    def __init__(self) -> None:
        pass
    
    def solution(self, n):
        result = None

        # TODO: 请在此编写代码

        return result

if __name__ == "__main__":
    n = [int(item) for item in input().strip().split()]
    s = Solution()
    result = s.solution(n)
    print(result)

【分析】

完成的总任务量需要大于或等于 n n n ,即
x + x k + ⋯ + x k t − 1 + ⋯ ≥ n x + \frac{x}{k} + \cdots + \frac{x}{k^{t-1}} + \cdots \geq n x+kx++kt1x+n
对于左边的式子,提出 x x x 后是首项为 1 1 1 ,公比为 1 k \frac{1}{k} k1 的等比数列,利用前n项求和公式,得
x × 1 × [ 1 − ( 1 k ) N ] 1 − 1 k = x × k k − 1 × ( 1 − 1 k N ) ≥ n x \times \frac{1 \times [1 - (\frac{1}{k})^{N}]}{1 - \frac{1}{k}} = x \times \frac{k}{k-1} \times (1 - \frac{1}{k^N}) \geq n x×1k11×[1(k1)N]=x×k1k×(1kN1)n
N → + ∞ N \to +\infty N+ ,所以 1 k N → 0 \frac{1}{k^N} \to 0 kN10 ,则
x ≥ n × k − 1 k x \geq n \times \frac{k-1}{k} xn×kk1
正当我以为做完的时候,结果发现不对,然后便换了二分法的思路最终解决了这道题。

比赛结束后仔细分析后知道,题目的意思应该是每天只能完成整数份的份数,而我的分析中, x k \frac{x}{k} kx 可能为小数,同时代入到后面的计算中,导致 x x x 偏小。

通过对 n × k − 1 k n \times \frac{k-1}{k} n×kk1 向上取整,大大缩小了 x x x 的范围,且正确答案也比 x x x 大一点,所以每次都对 x x x 加1,然后计算完成的总任务量是否大于或等于 n n n ,同时每天的完成的任务量需要大于1。

【代码】

以下代码并非比赛时提交的代码,但应该能通过。

# 请关闭中文输入法,用英文的字母和标点符号。
# 如果你想运行系统测试用例,请点击【执行代码】按钮,如果你想提交作答结果,请点击【提交】按钮,
# 注意:除答案外,请不要打印其他任何多余的字符,以免影响结果验证
# 本OJ系统是基于 OxCoder 技术开发,网址:www.oxcoder.com
# 模版代码提供基本的输入输出框架,可按个人代码习惯修改


class Solution:
    def __init__(self) -> None:
        pass
    
    def solution(self, n):
        result = None

        # TODO: 请在此编写代码
        k = n[1]
        n = n[0]
        x = (n * (k-1) // k) + 1

        while True:
            summ = 0
            t = 1
            while True:
                task = x//(k**(t-1))
                if task >= 1:
                    summ += task
                else:
                    break
                t += 1
            if summ >= n:
                break
            else:
                x += 1

        result = x
        return result

if __name__ == "__main__":
    n = [int(item) for item in input().strip().split()]
    s = Solution()
    result = s.solution(n)
    print(result)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值