FZU 2125.简单等式
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
福州大学第十届程序设计竞赛
给你n,m,让你根据公式求最小的x,一道暴力枚举题,但如果只是傻傻的暴力铁定超时,这时候要寻找一个跳出条件
根据等式,x是小于根号n的,n的范围是10的18次方,相当于x最大也才10的9次方,这时候关键点来了,跳出判断就根据s(x, m),想一下这个最大能到多少,x取最大10的9次方,m取最大16,手算一下,s(x, m)绝对不会超过90,那么问题就解决了
不过虽然这个问题解决了,我交的时候碰到了更奇葩的一个问题是,交的时候,用GNU C++交wa了,用Visual c++叫就A了,前些天就遇到这个问题了,还不知道为啥,问大神去了。。
刚去问了YL大神,他看了我代码,默默的说了一句,你用__int64代替long long试试,我了个去啊,还真A啦。最后查了一下,这是不同编译器下,long long 和 __int64是有差异的
long long 与 __int64的差异请戳:c/c++下 long long与__int64不同编译环境的比较
#include <stdio.h>
#include <math.h>
#include <string.h>
int s(int n, int m) {
int sum = 0;
while(n){
sum+=n%m;
n/=m;
}
return sum;
}
int main() {
int t;
scanf("%d", &t);
while(t--) {
long long n;
int m;
scanf("%lld %d", &n, &m);
int ans = -1;
int x = sqrt(n*1.0);
while(x){
if(n%x == 0){
int b = s(x, m);
if(n/x-x == b) {
ans = x;
}
}
if(n/x-x > 90)
break;
x--;
}
printf("%d\n", ans);
}
}