FZU 2125 简单的等式 【数学/枚举解方程式】

现在有一个等式如下: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

【分析】:从小到大枚举s(x,m),然后根据解二次方程的公式,x=(-b+-sqrt(b^2-4*a*c))/2,分别求出x的值,然后观察x是否满足x^2+s(x,m)x-n=0这个等式,如果满足,则输出x的值,因为告诉你了n和m的范围n(1<=n<=10^18),m(2<=m<=16)。所以最多枚举到200就可以了,另外福州大学用lld是WA,I64d则过。

【代码】:

#include <iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<streambuf>
#include<cmath>
using namespace std;
#define ll long long
#define oo 10000000
ll s(ll x,ll m)
{
    ll ans=0;
    while(x)
    {
        ans+=x%m;
        x/=m;
    }
    return ans;
}
int main()
{
    int t;
    ll n,m,x;
    int flag;

    scanf("%d",&t);
    while(t--)
    {
        flag=0;
        scanf("%I64d%I64d",&n,&m);//fzu不能用lld 不然WA
        for(int i=1;i<=100;i++)/*pow(2,100)已经是10的18次方了,所以也就是100了*/
        {
            x=(-i+sqrt(i*i+4*n))/2;//用x=(-b+sqrt(b*b-4*a*c))/2*a
            if(x*x+s(x,m)*x-n==0)
            {
                flag=1;
                break;
            }
        }
        if(flag==0) printf("-1
");
        else printf("%I64d
",x);
    }
}
解方程
原文地址:https://www.cnblogs.com/Roni-i/p/8013713.html