Finding the largest palindrome of the product of two three digit numbers problem

╄→尐↘猪︶ㄣ 提交于 2019-12-04 01:29:04

问题


So on Project Euler the Problem 4 states the following:

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.

I have tried the following:

    #include <stdio.h>
    #include <stdlib.h>

    int check(int result)
    {
        char b[7];
        sprintf(b, "%d", result);
        if (b[0] == b[5] && b[1] == b[4] && b[2] == b[3])
        {
            return 1;
        }
        else 
        {
            return 0;
        }
    }

    int main () {
        int i;
        int g;
        int final;
        for (i = 999; i > 99; i--)
        {
            for (g = 999; g > 99; g--)
            {
                if (check(g*i) == 1)
                {
                    final = g*i;
                    goto here;
                }
            }
        }
        here:
        printf("%d", final);
}

But, this does not work. Instead of the right answer, I get 580085, which I guess is a palindrome at least, but still not the right answer.

Let me explain my program starting from int main:

  1. int i and int g are my multipliers. They are those two three digit numbers.
  2. int final is the number that will store the largest palindrome.
  3. I start two for loops going to down to get every number possibility.
  4. I get out of the loop using a goto when the first palindrome is reached(probably should not but, it doesn't effect a small program like this too much).
  5. The first palindrome should be the biggest one possible since I am counting down from the top.

Let me now explain my check:

  1. First off since these are two three digit numbers multiplying together to determine the size a char would need to be to hold that value I went to a calculator and multiplied 999 * 999 and it ended up being 6 then I need to add one because I found out from one the questions I posted earlier that sprintf puts a \0 character at the end.
  2. Ok, now that I have a char and all, I copied result (which i*g in int main) and put it in char b[7].
  3. Then I just checked b to see if it equalled it self with by hard coding each slot I needed to check for.
  4. Then I returned accordingly, 1 for true, and 2 for false.

This seems perfectly logical to me but, it does not work for some weird reason. Any hints?


回答1:


This assumption is wrong:

The first palindrome should be the biggest one possible since I am counting down from the top.

You will check 999*100 = 99900 before 998*101 = 100798, so clearly you can´t count on that.




回答2:


The problem is that the first palindrome that you find is not the bigger one for sure.

Just an example:

i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800

The first one is smaller, but since you iterate first on i, then on g it will be discovered first.

Ok, they are not palindrome but the concept is the same..




回答3:


I think you are tackling this problem back to front. It would be more efficient to generate the palindromes from highest to lowest then check by factorizing them. First one that has two three digit factors is the answer.

e.g.

  bool found = false;
  for (int i = 998; i >= 100; i--)
  {
    char j[7];
    sprintf(j,"%d",i);
    j[3]= j[2];
    j[4]= j[1];
    j[5]= j[0];
    int x =atoi(j);
    int limit = sqrt((float) x);
    for (int z = 999; z >= limit; z--)
    {
      if (x%z==0){
        printf("%d",x);
        found = true;
        break;
      }
    }
    if (found) break;
  }



回答4:


The first palindrome should be the biggest one possible since I am counting down from the top

The problem is that you might have found a palindrome for a large i and a small g. It's possible that there's a larger palindrome that's the product of j and k where:

i > j and
g < k

(I hope this makes sense).




回答5:


Java Implementation:

public class Palindrome {

    public static void main(String[] args)
     {       int i, j;
            int m = 1;
            int k =11;
            boolean flag = false;

            while (true)
            {;
                if (flag) j = m + 1;
                else j = m;

                for (i = k; i > 0; i--)
                {

                    j++;



                    int number, temp, remainder, sum = 0;
                    number = temp = (1000 - i) * (1000 - j);

                    while (number > 0)
                    {
                        remainder = number % 10;
                        number /= 10;
                        sum = sum * 10 + remainder;
                    }

                    if (sum == temp)
                    {
                        System.out.println("Max value:"+temp);

                        return;
                    }


                }

                if (flag)
                    m++;
             k=k+11;
                flag = !flag;
            }

     }

}



回答6:


A word on performance. You have the possibility of duplicating many of the products because you are using a pretty simple nested loop approach. For instance, you start with 999*999 and then 999*998, etc. When the inner loop finishes, you will decrement the outer loop and start again with 998*999, which is the same as 999*998.

Really, what you want to do is start the inner loop with the same value as the current outer loop value. This will eliminate your duplicate operations. Something like this...

for (i = 999; i > 99; i--)
{
  for (g = i; g > 99; g--)
  {
...

However, as Emilio pointed out, your assumption that the first palindrome you find will be the answer is incorrect. You need to compute the biggest numbers first, obviously. So you should try them in this order; 999*999, 999*998, 998*998, 999*997, 998*997, etc...

Haven't tested it but I think you want something like this (pseudo code):

x = 999;
n = 0;

while (++n <= x)
{
  j = x;
  k = j - n;

  while (j >= k)
  {
    y = j-- * k;
    if (check(y))
      stop looking
  }
}



回答7:


I found this article which might help you. It has improved brute force approach.




回答8:


All the above provided answers are excellent, but still I could not restrict myself from writing the code. The code posted by @thyrgle is absolutely perfect. Only a slight correction which he needs to do is just check which product is the maximum. The code can be as

int i,j,max=0,temp;
for(i=999;i>=100;i--){
    for(j=i;j>=100;j--){
        temp=i*j;
        if(isPalin(temp) && temp>max){
            max=temp;
        }
    }
}
cout<<max<<"\n";



回答9:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int a[6];

void convertToString(int xy){
    int i,t=100000;
    for(i=0;i<6;i++){
        a[i]=xy/t;
        xy = xy % t;
        t=t/10;
    }
}

int check(){
    int i;
    for(i=0;i<3;i++){
        if(a[i]!=a[6-i]){
            return 0;
        }
    }
    return 1;
}

void main(){
    int x,y,xy,status=0;
    int i=0,j=0,p=0;
    for(x=999;x>99;x--){
        for(y=x;y>99;y--){
            xy=x*y;
            convertToString(xy);
            status = check();
            if(status==1){
                if(xy>p){
                    p=xy;
                    i=x;
                    j=y;
                }
            }
        }
    }

    printf("\nTwo numbers are %d & %d and their product is %d",i,j,p);

}



回答10:


x,y=999,999

k=0

pal=[]

while (y>99):
    while (x>=100):
        m=x*y
        n=x*y
        while (n!=0):
            k=k*10+(n%10)
            n=int(n/10)
        if(m==k):
            if k not in pal:
                pal.append(k)
        x=x-1
        k=0
    else:
        y,x=y-1,999


pal.sort()
print(pal)

it gives 906609 as the largest palindrome number



来源:https://stackoverflow.com/questions/3250957/finding-the-largest-palindrome-of-the-product-of-two-three-digit-numbers-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!