PE 4 Largest palindrome product(最大回文)

题目

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.

https://projecteuler.net/problem=1

分析

题目求由两三位数组成的最大回文数。(判断回文函数自定义为isPalindrome,maxPal表示最大回文,pal当前数积

解法1(暴力):两个嵌套for i = 100 to 999循环枚举出所有的两位数乘积,再判断回文,比较最大。时间复杂度为ON2

解法2:可以看到解法1重复了计算了两次,如101*100 100*101显然他们是一样的,可以将内循环初值设为外循环初值来解决。

解法3:从内循环判断看,ifisPalindrome{ifpal>maxPalmaxPal= pal }},我们要找最大的回文,可以先从最大的回文开始,

如果小于最大回文,则退出循环Break,不用执行多余的循环(内循环基数是递减的)

解法4:观察回文:10201, 11211, 12221, 13231..180081….

最大回文一定在6位数中,且

               P  =  100000x+10000y+1000z+100z+10y+x

                     =  100001x+1001y+1100z

=    11(9091x+910y+100z)

              P = 180081 ==11x9091x1+910x8+100x0= 11 x 16371,所以6位数的回文一定能被11整除。根据这一条件可以对解法3进行优化。

Code

 

#include <iostream>
#include <ctime>
using namespace std;

bool isPalindrome(int n);
int f1();
int f2();
int f3();
int f4();
int main(){
    double  start, end;
    start = clock();//取开始时间

    cout << "最大回文数为: " << f3()<<endl;

    end = clock();//取结束时间
    cout << "运行时间为: "<<(end - start)/CLOCKS_PER_SEC << "s";//计算程序运行时间
    return 0;
}
int f4(){
    int maxPal = 0;
    int pal = 0;
    int i,j;
    for (i= 100; i <= 999; i++)
    {
        int j = 999,db=1,times;
        if (i == 913){
            int a = 1;
        }
        if (i % 11 != 0){
            j = 990;//三位数以内最大的11的倍数的数990开始。
            db = 11;//divisible by 11
        }
        while (i<=j)
        {
                times = i*j;
                  if (times<maxPal)break;
                if (isPalindrome(times))//是回文数
                {
                    maxPal = times>maxPal ?times : maxPal;
                }
                j -= db;
                
        }
    }
    return maxPal;
}
int f3(){
    int maxPal = 0;
    int times = 0;
    for (int i = 100; i < 999; i++)
    {
        int j = i;
        for (j; j < 999; j++)
        {
            times = i*j;
            if (times<maxPal)break;
            if (times)
            if (isPalindrome(times)){//是回文数
                maxPal = times>maxPal ?times : maxPal;
            }
        }
    }
    return maxPal;
}
int f2(){
    int maxPal = 0;
    int times = 0;
    int i, j;
    for (i = 100; i < 999; i++)
    {
        j = i;
        for (j; j < 999; j++)
        {
            times = i*j;
            if (isPalindrome(times)){//是回文数
                maxPal = times > maxPal ? times : maxPal;
            }
        }
    }
    return maxPal;
}
int f1(){
    int maxPal = 0;
    int times = 0;
    for (int i = 100; i < 999; i++)
    {
        for (int j = 100; j < 999; j++)
        {
            times = i*j;
            if (isPalindrome(times)){//是回文数
                maxPal = times>maxPal ? times : maxPal;
            }
        }
    }
    return maxPal;
}
bool isPalindrome(int n){
    int number = n;
    int reversed = 0;
    while (n>0)
    {
        reversed = 10 * reversed + n % 10;
        n /= 10;
    }
    return number == reversed;
}

 

Mathematica  

 

palQ[x_] := With[{ls  = IntegerDigits[x]}, ls == Reverse[ls]]

Outer[Times, Range[100, 999], Range[100, 999]] // Flatten // Select@palQ // Max

只给除了暴力解法1的解法。其他解法的实现暂时不会待填..

参考:Lster

原文地址:https://www.cnblogs.com/dingblog/p/4499131.html