我对“算法和数据结构”课程有这个问题
你有一个方程式x ^ 2 + s(x)+ 200·x = N,其中x和N是自然数,S(x)是数字x的数字之和。
在输入上我们有N和A,B,A≤B和A,B≤1,000,000,000。您需要检查区间[A,B]中是否有自然数x来解决方程式。如果找到则需要返回该数字,否则返回-1。
Example Input:
1456
10 80
Output
-1
我设法通过使用一些数学和一些修改版本的强力算法来解决这个问题。但有没有更有效的(基于算法)方法来解决这个问题?
这是我的代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Range {
static int proveri(long N, long A, long B) {
long res = 0;
long start = (long)((-200 + Math.sqrt(4*N + 4))/2);
//System.out.println(start);
for (long i = Math.max(A, start); i <= B; i++) {
res = i * i + S(i) + 200 * i;
if(res == N)
return (int)i;
if(res > N)
return -1;
}
return -1;
}
static int S(long x) {
int sum = 0;
while(x > 0) {
sum += x % 10;
x /= 10;
}
return sum;
}
public static void main(String[] args) throws Exception {
int i,j,k;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long N = Long.parseLong(br.readLine());
StringTokenizer st = new StringTokenizer(br.readLine());
long A = Long.parseLong(st.nextToken());
long B = Long.parseLong(st.nextToken());
int res = proveri(N, A, B);
System.out.println(res);
br.close();
}
}
答案 0 :(得分:1)
在这里,您可以减少必须搜索的数字量。
考虑方程a n x n + a n-1 x n-1 + ... + a 1 x + a 0 = 0。 理性根定理表明如果x = p / q是一个解, 然后p除 0 ,q除以 n
在您的情况下, n 为1, 0 等于S(x)-N。因此,我们知道任何解决方案都必须划分S(x)-N。
这是ben75的提示所在。由于S(x)不能大于81,我们可以循环遍历S(x)的所有可能值,并单独求解。像这样:
for each possible value of S(x)
loop through every factor x of S(x) - N
check if it is between A and B, if its digits sum to S(x)
and if it is a solution to x*x + 200x + S(x) = N.
if it is, return it.
return -1
你也可以通过一种非常灵活的方式来浏览一个数字的所有因素,但是我会让你自己解决这个因素,因为这是一个课程。我的提示是看一个数字的素数因子化。
答案 1 :(得分:0)
对于等式x ^ 2 + s(x)+ 200·x = N,请考虑
x^2 + 200·x + (N - s(x)) = 0
对于带整数解的* x ^ 2 + b * x + c = 0方程的解,我们需要:
b^2 - 4*a*c >= 0 and must be a perfect square
因此200 ^ 2 - 4 *(N - s(x))&gt; = 0和一个正方形或
10000&gt; =(N - s(x))和(10,000 - (N - s(x))必须是一个正方形。因此,平方值小于10,000,因此最多可以有100个值需要检查。使用适当的N值可能会更小。
还要注意,因为N < 10,000,s(x)最多可以是36.这些应该会相当大一些。