AtCoder Grand Contest 066 B. Decreasing Digit Sums(构造 打表找规律)

题目

给定一个n(n<=50),记f(x)是x各数位的加和,例如f(331)=3+3+1=7

要求输出一个x(1\leq\ x \leq 10^{10000}),且对于任意i∈[1,n],均有f(2^{i-1}x)>f(2^ix)成立

思路来源

jiangly B站讲解

题解

首先n没啥用,构造一个n=50成立的case即可,

给定一个x,将x乘以2后,数位和变小,乘以50次都变小

考虑变小怎么做,逆向考虑,

假设终态是10000(若干个0),如果*2=10000变小,

前一项就是5000,这样不断除以2,2500,1250,...

发现前面若干项是变小的,中间也有变大的

乘以若干个2得到最后的10000,那么原始就是不带2的,也就是5的j次方

构造5的j次方,每个*2的时候,都会变小几次,然后变大一次,整体趋势变小,偶有变大

拼接到一起,就能抵消这个偶有变大的情况,只要整体趋势是变小多,变大少

打表发现拼接5的1次方到5的100次方即可,总长度也没有超限

也可以中间补0让各段独立,不过删掉0发现也没有违反性质

Bonus

考虑变大怎么做,

手玩发现,9的时候,会变大,如9,18,36,72,144,288,

144->288会变大,具体打表可以后面虽然有变小的时候,但整体的趋势是变大

拼接9,18,36这些数即可,例如9000000001800000036...

只要整体趋势是变大多,变小少,

且拼接的足够长,那么整体趋势一定是变大

代码

# def f(n):
#     s = str(n)
#     ans = 0
#     for c in s:
#         ans += ord(c) - ord('0')
#     return ans

s = ''
for i in range(100):
    v = 5 ** i
    s += str(v)
n = int(s)
print(n)
# for i in range(51):
#     print(f"i:{i} f:{f(n)}")
#     n*=2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值