codeforces1120E The very same Munchhausen

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yzyyylx/article/details/88234989

题面

题意

给出一个正整数a,问是否存在一个正整数n,满足 S ( a n ) = S ( n ) / a S(a*n)=S(n)/a n < = 1 0 500000 n<=10^{500000}
S ( x ) S(x) 表示x各个数位的数字和。

做法

首先可以考虑把n分成多个部分,使n形如 b 1 + b_1+ "0000" + b 2 + +b_2+ “0000” + b 3 . . . . . . b k +b_3......b_k
这样每一部分就相互独立了,只要满足 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 即可。
我们可以根据 a S ( a b i ) S ( b i ) = 0 a*S(a*b_i)-S(b_i)=0 的正负将 b i b_i 分成两类,要求这两类的和的绝对值相等。
因为500000很大,所以其实在大多数的情况下,只要满足等式,一般都不会超过范围。
所以可以让每类 b i b_i 分别相等,这样我们只要找到两个数 x , y x,y ,使 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 ,然后 x , y x,y 再各自反复多次即可。
不难发现 x = 1 x=1 肯定符合条件( a = 1 a=1 时要特判)。
现在就要找到满足 a S ( a y ) S ( y ) < 0 a*S(a*y)-S(y)<0 的y。
显然要让 S ( a y ) S(a*y) 尽可能小,那我们就可以考虑让它大于等于 1 0 i 10^i ,且尽可能的接近 1 0 i 10^i
可以考虑枚举i,令 y = 1 0 i s y=\lceil \frac{10^i}{s} \rceil ,然后看看是否满足 a S ( a y ) S ( y ) < 0 a*S(a*y)-S(y)<0 ,如果满足计算此时的总长度是否小于等于500000,满足则输出,否则继续,注意特判一下a是 1 0 i 10^i 的因数的情况。
这个构造n的方案显然不是使n最小的,但是就此题 n < = 1 0 500000 n<=10^{500000} 来说,已经足够了。

代码

#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;
}

猜你喜欢

转载自blog.csdn.net/yzyyylx/article/details/88234989