如题,前一阵有几个同学去面试回来后说又一道编程题不会,出于好奇大家就讨论了这道题,后来发现该题难度不大不过一定要动些小脑筋不然采用穷举法也确实是算不出来的。
由于画图实在是不在行,所以就画了一个简略的图:
下面给出解题的代码:
import java.lang.Math; public class Gj{ public static void main(String [] args) { int N=0; long r_square=2000000000000L; long r=0; double r_double=Math.sqrt(r_square); long r_long=(long)r_double; double y_double=0.0; long y_long=0; if(r_double==r_long) { r=r_long-1; N=N+1; } else {r=r_long;} for(long x=1;x<=r;x++) { y_double=Math.sqrt(r_square-x*x); y_long=(long)y_double; if(y_long==y_double) { if(x*x+y_long*y_long==r_square) { /* System.out.print(x); System.out.print(", "); System.out.println(y_long); */ N=N+1; } } } System.out.println(4*N); } }
总体的解题思路就是采用勾股定理,给定一个整数坐标X,假设存在整数Y满足 X**2+Y**2=R**2 ,那么我们可以求出该Y值, 然后就是判断 该Y 值是否是整数。
经过验证,以上代码可以正确的求出答案。
后记,在上面的解答后 其实还可以进一步改进的,上面思路是对 1/4 圆求解,我们其实还是可以对其再切分的。
因为, 2* ( (sqrt(2)/2 * R)**2 ) == R**2 , 也就是说 0<X<sqrt(2)/2 * R , sqrt(2)/2 * R < Y < R , 而这就意味着我们只需要 求 0<X<sqrt(2)/2 * R 这段距离后乘以2 便是上面 代码的效果,因为是对称的原因(当然还要验证 sqrt(2)/2 * R 是否为整数,当然这个不可能是整数的, 可以忽略)。
由于这个改进并没有提高算法的时间复杂度,只是线性的提高一倍运算速度, 代码就不放上面了。