题面
题意
给出一个正整数a,问是否存在一个正整数n,满足
S
(
a
∗
n
)
=
S
(
n
)
/
a
S(a*n)=S(n)/a
S(a∗n)=S(n)/a且
n
<
=
1
0
500000
n<=10^{500000}
n<=10500000
S
(
x
)
S(x)
S(x)表示x各个数位的数字和。
做法
首先可以考虑把n分成多个部分,使n形如
b
1
+
b_1+
b1+"0000"
+
b
2
+
+b_2+
+b2+“0000”
+
b
3
.
.
.
.
.
.
b
k
+b_3......b_k
+b3......bk
这样每一部分就相互独立了,只要满足
∑
i
=
1
k
a
∗
S
(
a
∗
b
i
)
−
S
(
b
i
)
=
0
\sum_{i=1}^{k}a*S(a*b_i)-S(b_i)=0
∑i=1ka∗S(a∗bi)−S(bi)=0即可。
我们可以根据
a
∗
S
(
a
∗
b
i
)
−
S
(
b
i
)
=
0
a*S(a*b_i)-S(b_i)=0
a∗S(a∗bi)−S(bi)=0的正负将
b
i
b_i
bi分成两类,要求这两类的和的绝对值相等。
因为500000很大,所以其实在大多数的情况下,只要满足等式,一般都不会超过范围。
所以可以让每类
b
i
b_i
bi分别相等,这样我们只要找到两个数
x
,
y
x,y
x,y,使
a
∗
S
(
a
∗
x
)
−
S
(
x
)
>
0
a*S(a*x)-S(x)>0
a∗S(a∗x)−S(x)>0且
a
∗
S
(
a
∗
y
)
−
S
(
y
)
<
0
a*S(a*y)-S(y)<0
a∗S(a∗y)−S(y)<0,然后
x
,
y
x,y
x,y再各自反复多次即可。
不难发现
x
=
1
x=1
x=1肯定符合条件(
a
=
1
a=1
a=1时要特判)。
现在就要找到满足
a
∗
S
(
a
∗
y
)
−
S
(
y
)
<
0
a*S(a*y)-S(y)<0
a∗S(a∗y)−S(y)<0的y。
显然要让
S
(
a
∗
y
)
S(a*y)
S(a∗y)尽可能小,那我们就可以考虑让它大于等于
1
0
i
10^i
10i,且尽可能的接近
1
0
i
10^i
10i。
可以考虑枚举i,令
y
=
⌈
1
0
i
s
⌉
y=\lceil \frac{10^i}{s} \rceil
y=⌈s10i⌉,然后看看是否满足
a
∗
S
(
a
∗
y
)
−
S
(
y
)
<
0
a*S(a*y)-S(y)<0
a∗S(a∗y)−S(y)<0,如果满足计算此时的总长度是否小于等于500000,满足则输出,否则继续,注意特判一下a是
1
0
i
10^i
10i的因数的情况。
这个构造n的方案显然不是使n最小的,但是就此题
n
<
=
1
0
500000
n<=10^{500000}
n<=10500000来说,已经足够了。
代码
#include<bits/stdc++.h>
#define ll long long
#define Z 5
#define MN 500000
#define N 500100
using namespace std;
ll a,g,A,B,sum;
string num,zero,ans;
inline ll gcd(ll u,ll v)
{
for(;v;)
{
u%=v;
swap(u,v);
}
return u;
}
inline ll S(ll u)
{
ll res=0;
for(;u;u/=10) res+=u%10;
return res;
}
int main()
{
ll i,j,tmp,t;
for(i=1;i<=Z;i++) zero+='0';
cin>>a;
if(a==1)
{
puts("1");
return 0;
}
B=S(a)*a-1;
for(i=0,tmp=1;tmp;i++)
{
if(num[num.size()-1]!='9' && a*(S(a-tmp)+1)<sum+1)
{
A=sum+1-a*(S(a-tmp)+1);
g=gcd(A,B);
if((A/g)*(Z+1)+(B/g)*(Z+num.size())<=MN)
{
num[num.size()-1]++;
break;
}
}
tmp=tmp*10;
t=tmp/a;
sum+=t;
if(num.size() || t) num+=t+'0';
tmp%=a;
}
if(!tmp)
{
if(a>sum)
{
puts("-1");
return 0;
}
else if(a==sum)
{
cout<<num;
return 0;
}
A=sum-a;
g=gcd(A,B);
}
for(i=1;i<=(B/g);i++) ans+=num+zero;
for(i=1;i<=(A/g);i++) ans+="1"+zero;
cout<<ans;
}