• [Project Euler] 来做欧拉项目练习题吧: 题目004


                                                     [Project Euler] 来做欧拉项目练习题吧: 题目004

                                                                     周银辉

    问题描述:

    A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

    Find the largest palindrome made from the product of two 3-digit numbers. 

    (先思考,如果有兴趣先编程试试,然后才看下面的内容)   

    问题分析:

    求两个三位数相乘能都得到的最大回文数(回文:从前到后阅读和从后向前阅读都一样) 

    很简单的思路:a: 100~999  b: 100~999 ,然后对每个a*b进行判断其是否是回文数,然后在找出最大的。

    先看如何判断一个数(比如9119)是否是回文数。

    你可以利用itoa和strrev将其转换成字符串,然后调用字符串反转函数,最后看反转后的字符串和原字符串是否相等,但我更建议下面的方法:

    int is_palindromic(int n)
    {
    int reverse   = 0;
    int quotient  = n;
    int remainder = 0;
    while(quotient > 0)
    {
    remainder = quotient%10;
    quotient  = quotient/10;
    reverse   = reverse*10 + remainder;  
    }
    //test
    //printf("reversed:%d\n", reverse);
    return n==reverse;
    }

    然后是挨个去试乘积是否是回文数,并找出最大的:

    int a, b, c, max=0;

    for(a=100; a<=999; a++)

    {

      for(b=100; b<=999; b++)

      {

        c = a*b;

        if(is_palindromic(c) && c>max)

        {

          max = c; 

        } 

      } 

    但注意到,上面的两个for循环是可以优化的:

    由于,题目要求的是最大的回文数而不是求所有的,所以for循环应该从999向100递减,这样当发现当前的c值小于上一次计算出来的回文数时,就可以停止循环了,因为接下来的值会更小:

    int a, b, c, max=0;

    for(a=999; a>=100; a--)

    {

      for(b=999; b>=100; b--)

      {

        c = a*b;

        if(c<max)

        {

          break;

        } 

        if(is_palindromic(c))

        {

          max = c; 

        } 

      } 

    再来,由于乘法具有交换律,所以a=x, b=y 和 a=y, b=x所得乘积是一样的,那么上面的两层循环存在重复运算,最简单的例子是a=1,b=999时和a=999, b=1时,所以代码可以写成:

    int Test()
    {
    int i, j, product;
    int max = 0;
    int best_i, best_j, times=0;//just for test
    for(i=999; i>100; i--)
    {
    for(j=999; j>=i; j--)//正常写法时j>100,但为减少比较次数j>=i就可以了
    {
    times++;
    product = i*j;
    if(product>max && is_palindromic(product))
    {
    max = product;
    best_i=i;
    best_j=j;
    break;//对于更小的j没必要比较了,因为其必定小于max
    }
    }
    }
    //test
    printf("%d * %d, call times %d\n", best_i, best_j, times);
    return max;
    }

    注:当完成题目后,对于某些题,官方网站会给出参考答案,在我的博客里不会将官方答案贴出来,仅仅会写下我自己当时的思路,除非两者不谋而合。另外,如果你有更好的思路,请留言告诉我,我非常乐意参与到讨论中来。 

  • 相关阅读:
    SQL函数——LENGTH()和LENGTHB()
    简单实用的Windows命令(二)
    简单实用的Windows命令(一)
    简单jQuery实现选项框中列表项的选择
    .net开发笔记(十六) 对前部分文章的一些补充和总结
    .Net开发笔记(十五) 基于“泵”的TCP通讯(接上篇)
    .Net开发笔记(十四) 基于“泵”的UDP通信(接上篇)
    .net开发笔记(十三) Winform常用开发模式第一篇
    .net开发笔记(十二) 设计时与运行时的区别(续)
    Mybatis Spring multiple databases Java configuration
  • 原文地址:https://www.cnblogs.com/zhouyinhui/p/1935824.html
Copyright © 2020-2023  润新知