笨鸟

天道酬勤,思者常新;博观约取,厚积薄发;心如止水,气贯长虹;淡泊明志,宁静致远。
posts - 10, comments - 0, trackbacks - 0, articles - 1

2010年11月23日

由于javaeye现在可以访问,下面的内容将在javaeye中,博客地址http://clumsybird.javaeye.com

posted @ 2010-11-24 17:56 ClumsyBird 阅读(165) | 评论 (0)编辑 收藏

     摘要: 问题描述如下:     “一个20*20的数组如下所示          08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08      ...  阅读全文

posted @ 2010-11-24 16:03 ClumsyBird 阅读(228) | 评论 (0)编辑 收藏

    问题描述如下:
        “10以下的质数之和为2+3+5+7=17,求2000000以下的质数之和?”

    此问题相对比较简单,在前面的问题中已经给出质数判断的方法,具体代码如下:
/**
     * 判断是否是素数
     * 
     * 
@param n
     * 
@return
     
*/

    
public static boolean isPrimeNumber(int n) {
        
if (n < 2{
            
return false;
        }

        
double max = Math.sqrt(n);
        
for (int i = 2; i <= max; i++{
            
if (n % i == 0{
                
return false;

            }

        }

        
return true;
    }

    问题的实现方法如下:
/**
     * 小于n的质数之和
     * 
@param n
     * 
@return
     
*/

    
private static Long getPrimeNumberSum(int n) {
        
int i = 2;
        Long sum 
= 2L;
        
while (i <= n) {
            
if (AlgorithmUtil.isPrimeNumber(++i)) {
                sum 
+= i;
            }

        }

        
return sum;
    }

    即可得到答案142913828922

    稍稍优化一下,
    /**
     * 小于n的质数之和
     * 
     * 
@param n
     * 
@return
     
*/

    
private static Long getPrimeNumberSum(int n) {
        
int i = 5;
        Long sum 
= 5L;//由于2,3都是质数,初始值为5
        while (i <= n) {
            
if (AlgorithmUtil.isPrimeNumber(i += 2)) {//质数 不能被2整除
                sum += i;
            }

            
if (i <= n && AlgorithmUtil.isPrimeNumber(i += 4)) {//不能被3整除
                sum += i;
            }

        }

        
return sum;
    }
    还可以通过埃拉托斯特尼筛法(http://zh.wikipedia.org/zh-cn/%E5%9F%83%E6%8B%89%E6%89%98%E6%96%AF%E7%89%B9%E5%B0%BC%E7%AD%9B%E6%B3%95)来质数之和。

    请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 17:22 ClumsyBird 阅读(386) | 评论 (0)编辑 收藏

    问题描述如下:
        “毕达哥拉斯三元数组存在{a,b,c},a<b<c,使得a^2+b^2=c^2,如3^2+4^2=5^2=25,求a,b,c满足以上条件,并使a+b+c=1000,给出a*b*c的值。”

    代码如下:
/**
     * 求毕达哥拉斯三元数组{a,b,c},使得a+b+c=target . 毕达哥拉斯三元数组存在{a,b,c},a<b<c,使得a^2+b^2=c^2
     * a > 3,(target-(a+b))^2=c^2=a^2+b^2 --> target^2=2*target*(a+b)-2ab
     * 
     * 
@return
     
*/

    
private static int getNumber(int target) {
        
int a = 0;
        
int b = 0;
        
int c = 0;
        
for (int i = 3; i < target; i++{
            
for (int j = i; j < target; j++{
                
if (target * target == 2 * target * i + 2 * target * j - 2 * i
                        
* j) {// target^2=2*target*(a+b)-2ab
                    a = i;
                    b 
= j;
                    
break;
                }

            }

        }

        c 
= target - a - b;
        
return a * b * c;
    }

    具体的分析可以看代码注释。得出结果31875000。
    除了直接的办法,应该还有另外的方法来求,保持未完待续状态。
    请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 17:09 ClumsyBird 阅读(335) | 评论 (0)编辑 收藏

    问题描述如下:
        “对于1000位数值求出连续五位数值的最大乘积,1000位连续数值如下:
                    73167176531330624919225119674426574742355349194934
        96983520312774506326239578318016984801869478851843
        85861560789112949495459501737958331952853208805511
        12540698747158523863050715693290963295227443043557
        66896648950445244523161731856403098711121722383113
        62229893423380308135336276614282806444486645238749
        30358907296290491560440772390713810515859307960866
        70172427121883998797908792274921901699720888093776
        65727333001053367881220235421809751254540594752243
        52584907711670556013604839586446706324415722155397
        53697817977846174064955149290862569321978468622482
        83972241375657056057490261407972968652414535100474
        82166370484403199890008895243450658541227588666881
        16427171479924442928230863465674813919123162824586
        17866458359124566529476545682848912883142607690042
        24219022671055626321111109370544217506941658960408
        07198403850962455444362981230987879927244284909188
        84580156166097919133875499200524063689912560717606
        05886116467109405077541002256983155200055935729725
        71636269561882670428252483600823257530420752963450

                
                如:红色表示的连续5位数57831,其乘积为5*7*8*3*1”
    代码实现如下:

private static int getGreatestProductBy(String s) {
        
int max = 0;
        
for (int i = 0; i < s.length() - 5; i++{
            
int temp = Integer.parseInt(s.charAt(i) + "")
                    
* Integer.parseInt(s.charAt(i + 1+ "")
                    
* Integer.parseInt(s.charAt(i + 2+ "")
                    
* Integer.parseInt(s.charAt(i + 3+ "")
                    
* Integer.parseInt(s.charAt(i + 4+ "");
            
if (temp > max) {
                max 
= temp;
            }

        }

        
return max;
    }

得答案40824

    请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 15:21 ClumsyBird 阅读(236) | 评论 (0)编辑 收藏

    问题描述如下:
        “前6个质数为:2,3,5,7,11,13,那第6个质数为13,求第10001个质数。”
    代码如下:
private static int getPrimeNumberBy(int n) {
        
int j = 1;
        
int i = 1;
        
int result = 0;
        
while (j < n) {
            
if (AlgorithmUtil.isPrimeNumber(i)) {
                result 
= i;
                j
++;
            }

            i 
+= 2;
        }

        
return result;
    }
    下面是判断质数的代码:
/**
     * 判断是否是素数
     * 
     * 
@param n
     * 
@return
     
*/

    
public static boolean isPrimeNumber(int n) {
        
if (n < 2{
            
return false;
        }

        
double max = Math.sqrt(n);
        
for (int i = 2; i <= max; i++{
            
if (n % i == 0{
                
return false;

            }

        }

        
return true;
    }
    ps:质数也叫素数。

    请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 13:56 ClumsyBird 阅读(853) | 评论 (0)编辑 收藏

    问题描述如下:
        “1到10的平方和为:1^2 + 2^2 + ... + 10^2 = 385,和平方为:(1 + 2 + ... + 10)^2 = 55^2 = 3025,他们之间的差为3025-385=2640,求1到100的和平方与平方和之间的差值?”

    代码实现如下:

    /**
     * 求前n个自然数和平方与平方和之差
     * 
@param n
     * 
@return
     
*/

    
private static int getDifference(int n) {
        
int first = 0;
        
int second = 0;
        
for (int i = 1; i <= n; i++{
            first 
+= i * i;
            second 
+= i;
        }

        
return second * second - first;
    }
    可以得到答案25164150。

    我们还可以使用数学的方法来解此题。
    1^2 + 2^2 + ... + n^2 =n(n+1)(2n+1)/6
    (1+2+3+...+n)^2 =(n(n+1)/2)^2
    相关证明可以去具体的了解,如:
    (n+1)^3 -(n-1)^3 =6n^2+2提示:证明平方和公式,1到n的求和公式就不提示了
    给出代码:

    private static int getDifference1(int n) {
        
return (n*(n+1)/2)*(n*(n+1)/2)-n*(n+1)*(2*n+1)/6;
    }

    到此结束,请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 13:37 ClumsyBird 阅读(551) | 评论 (0)编辑 收藏

    问题叙述如下:
    “2520是最小的数能够整除1到10,求能被1到20所整除的最小的数?”
  代码如下:

/**
     * 数字i从m到n,遍历,如果i不能被result整除,我们就将i除以i与result的最大公约数,并与当前result想乘
     *
     
*/

    
private static int getNumber(int m, int n) {
        
int result =
 n;
        
for (int i = n - 1; i >= m; i--
{
            
if (result % i != 0
{
                result 
*= i/
gcd(result,i);
            }

        }

        
return result;
    }


    
/**
     * 最大公约数:欧几里德算法 定理:gcd(a,b) = gcd(b,a mod b)
     * 
     * 
@param a
     * 
@param
 b
     * 
@return

     
*/

    
private static int gcd(int a, int b) {
        
if (b != 0
)
            
return gcd(b, a %
 b);
        
else

            
return a;
    }

    调用getNumber(1,20)即可得到答案232792560
    由于在此用到最大公约数,所以在下面给出了一些实现。

    /**
     * 最大公约数:欧几里德算法
     * 
@param a
     * 
@param
 b
     * 
@return

     
*/

    
private static int gcd1(int a, int b) {
        
if (a > b) 
{
            gcd1(b, a);
        }

        
int temp = 0;
        
for (; b != 0;) 
{
            temp 
= a %
 b;
            a 
=
 b;
            b 
=
 temp;
        }

        
return a;
    }


    
/**
     * 最大公约数:Stein算法 gcd(ka,kb) = k gcd(a,b),也就是最大公约数运算和倍乘运算可以交换,
     * 特殊的,当k=2时,说明两个偶数的最大公约数必然能被2整除
     * 
     * 
@param a
     * 
@param
 b
     * 
@return

     
*/

    
private static int gcdByStein(int a, int b) {
        
if (a > b) 
{
            gcdByStein(b, a);
        }

        
if (b == 0{
            
return
 a;
        }

        
if (a % 2 == 0 && b % 2 == 0{
            
return 2 * gcdByStein(a / 2, b / 2);//a,b都是偶数

        }

        
if (a % 2 == 0{
            
return gcdByStein(a / 2, b);//仅a为偶数

        }

        
if (b % 2 == 0{
            
return gcdByStein(a, b / 2);//仅b为偶数

        }

        
return gcdByStein((a + b) / 2, (a - b) / 2);//a,b都是奇数
    }

    如果有其他的方法,也请贴出大家一起讨论。^_^
    请不吝赐教。
    @anthor ClumsyBird

posted @ 2010-11-23 13:14 ClumsyBird 阅读(261) | 评论 (0)编辑 收藏