題面
題意
給出一個正整數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;
}