版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yzyyylx/article/details/88234989
题面
题意
给出一个正整数a,问是否存在一个正整数n,满足
且
表示x各个数位的数字和。
做法
首先可以考虑把n分成多个部分,使n形如
"0000"
“0000”
这样每一部分就相互独立了,只要满足
即可。
我们可以根据
的正负将
分成两类,要求这两类的和的绝对值相等。
因为500000很大,所以其实在大多数的情况下,只要满足等式,一般都不会超过范围。
所以可以让每类
分别相等,这样我们只要找到两个数
,使
且
,然后
再各自反复多次即可。
不难发现
肯定符合条件(
时要特判)。
现在就要找到满足
的y。
显然要让
尽可能小,那我们就可以考虑让它大于等于
,且尽可能的接近
。
可以考虑枚举i,令
,然后看看是否满足
,如果满足计算此时的总长度是否小于等于500000,满足则输出,否则继续,注意特判一下a是
的因数的情况。
这个构造n的方案显然不是使n最小的,但是就此题
来说,已经足够了。
代码
#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;
}