Accept: 114 Submit: 492
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
现在有一个等式如下:x^2+s(x,m)x-n=0。其中s(x,m)表示把x写成m进制时,每个位数相加的和。现在,在给定n,m的情况下,求出满足等式的最小的正整数x。如果不存在,请输出-1。
Input
有T组测试数据。以下有T(T<=100)行,每行代表一组测试数据。每个测试数据有n(1<=n<=10^18),m(2<=m<=16)。
Output
输出T行,有1个数字,满足等式的最小的正整数x。如果不存在,请输出-1。
Sample Input
4
4 10
110 10
15 2
432 13
Sample Output
-1
10
3
18
Source
福州大学第十届程序设计竞赛
这个题目还是很经典的,我们不知道sum(x,m)是多少,但是我们可以估计一下,我用电脑算了一下,pow(2,57)已经是10的18次方了,所以k可以开大点,最大不超过100,我们用x=(-b+sqrt(b*b-4*a*c))/2*a,就可以了。
把sum(x,m)当成一个已知的量来对待。即x*x+i*x-n=0;先求出x,然后判断x*x+s(x,m)*x-n=0;
#include<stdio.h>
#include<math.h>
long long s(long long n,long long m)
{
long long sum=0;
while(n)
{
sum+=n%m;
n=n/m;
}
return sum;
}
int main()
{
int t,flag;
long long i,n,m,x;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&m);
flag=0;
for(i=1;i<=100;i++)
{
x=(long long )(-i/2+sqrt(i*i+4*n)/2);
if(x*x+s(x,m)*x==n)//写成if(i==s(x,m))就不对了,不是很明白为什么,有可能是精度问题吧。
{
flag=1;
break;
}
}
if(flag==0)
printf("-1\n");
else
printf("%I64d\n",x);
}
return 0;
}
#include<stdio.h>
#include<math.h>
long long f(long long n,long long m)
{
long long sum=0;
while(n)
{
sum+=n%m;
n=n/m;
}
return sum;
}
int main()
{
int t,flag;
long long i,num,x,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&m);
i=(long long )sqrt(n*1.0);
num=i;
flag=0;
while(i>=num-100&&i>=0)
{
if(i*i+f(i,m)*i==n)
{
flag=1;
x=i;
}
i--;
}
if(flag==0)
printf("-1\n");
else
printf("%I64d\n",x);
}
return 0;
}