【Codeforces 1120E】The very same Munchhausen
构造。
题目大意:
给定一个正整数 $a$。
定义 $S(x)$ 表示 $x$ 的各个数位上的数字之和。
要求找到一个正整数 $n$ 满足:
注意必须除尽。
输出任意一个答案。答案不能超过 $5\times 10^5$ 位。
不存在输出 $-1$。
题解:
题目中的式子相当于 $a\times S(a\times n)-S(n)=0$。
由于$a\leq 1000$,我们可以构造一个数 $n=b_1000b_2000b_3000\cdots$,设一共有 $k$ 个这样的 $b$。
那么相当于要求 $\sum\limits_{i=1}^k a\times S(a\times b_i)-S(b_i)=0$。
较为简单地,我们可以选择一个 $x$ 和一个 $y$ 满足:
当然如果直接找到恰好为 $0$ 的则可以直接输出。
假设我们找到了这样的两个数,那么我们显然可以将 $x$ 和 $y$ 分别重复若干次,使得它们的和为 $0$。
对于 $x$,容易发现 $x=1$ 就是一个不错的答案。我们考虑寻找靠谱的 $y$。
为了满足条件,我们想要使 $S(a\times y)$ 的值尽可能小,那么就希望 $a\times y$ 尽可能接近 $10^m$ 并且大于等于它。
我们就从 $m=1$ 开始逐渐递增,然后计算出 $y=\lceil\frac{10^m}{a}\rceil$,再对当前的 $y$ 进行验证即可。
$y$ 的值和 $S(y)$ 的值都可以递推,$S(a\times y)$ 的值也容易通过余数进行计算。
然后判一下最终长度是否不超过 $5\times 10^5$ 即可。
注意我们计算 $y$ 时存的是下取整的结果,如果遇到进位会比较麻烦,因此可以直接跳过进位的情况。
这样就可以找到满足条件的答案。如果 $m$ 枚举了非常大都无法找到答案,就可以认为无解。
在 $2\leq a\leq 1000$ 时都能输出正确答案。
Code:
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
string num;
int a;
inline int S(int n){
int k=0;
while(n)k+=n%10,n/=10;
return k;
}
int main(){
scanf("%d",&a);
if(a==1)return puts("1"),0;
int X=a*S(a)-1,k=1,nw=0;
while(k<a)k*=10;
for(;num.length()<200000;){
int dig=k/a;k%=a;
num+=(char)(dig^'0');
nw+=dig;
if(dig!=9||k==0){
int rest=(a-k)%a,sr=S(rest)+1;
if(rest)++dig,++nw,++num.back();
if(sr*a<=nw){
int Y=nw-sr*a;
if(Y==0){
puts(num.c_str());
return 0;
}
long long g=1LL*X*Y/__gcd(X,Y);
if(4*g/X+(num.length()+3LL)*(g/Y)<=499000){
for(int i=1;i<=g/X;++i)printf("1000");
for(int i=1;i<=g/Y;++i)printf("%s000",num.c_str());
return 0;
}
}
if(rest)--dig,--nw,--num.back();
}
k*=10;
}
puts("-1");
return 0;
}