寻找两个三位数乘积的最大回文数问题

发布于 2024-09-10 09:29:44 字数 1839 浏览 7 评论 0原文

因此,在 Project Euler 上,问题 4 说明如下:

回文数读起来是一样的 双向。制作的最大回文数 两个 2 位数字的乘积 数字是 9009 = 91 99。

找到最大的回文 两个 3 位数的乘积。

我尝试过以下方法:

    #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);
}

但是,这不起作用。我得到的不是正确答案,而是 580085,我猜这至少是一个回文,但仍然不是正确答案。

让我从 int main 开始解释我的程序:

  1. int iint g 是我的乘数。它们就是那两个三位数。
  2. int Final 是将存储最大回文的数字。
  3. 我开始两个 for 循环,一直向下以获得每个数字的可能性。
  4. 当到达第一个回文时,我使用 goto 退出循环(可能不应该,但是,它不会对这样的小程序产生太大影响)。
  5. 第一个回文应该是最大的回文,因为我是从顶部倒数的。

现在让我解释一下我的检查:

  1. 首先,因为这些是两个三位数相乘以确定一个字符需要保持该值的大小,所以我使用计算器并乘以 999 * 999,最终得到 6,然后我需要添加一个,因为我从我之前发布的一个问题中发现 sprintf 在末尾添加了一个 \0 字符。
  2. 好的,现在我有了一个 char 和所有内容,我复制了 result (其中 i*gint main 中)并将其放入 char b[7]
  3. 然后我只是通过对我需要检查的每个插槽进行硬编码来检查 b ,看看它是否等于它自己。
  4. 然后我相应地返回了,1为true,2为false。

这对我来说似乎完全合乎逻辑,但是由于某些奇怪的原因它不起作用。有什么提示吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

再可℃爱ぅ一点好了 2024-09-17 09:29:44

这个假设是错误的:

第一个回文应该是最大的回文,因为我是从顶部倒数的。

您将在 998*101 = 100798 之前检查 999*100 = 99900,所以显然您不能指望这一点。

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.

魂牵梦绕锁你心扉 2024-09-17 09:29:44

问题是你找到的第一个回文肯定不是更大的。

举个例子:

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

第一个较小,但由于您首先在 i 上迭代,然后在 g 上迭代,它将首先被发现。

好吧,它们不是回文,但概念是相同的..

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..

坚持沉默 2024-09-17 09:29:44

我认为你正在从头到尾解决这个问题。从最高到最低生成回文,然后通过因式分解进行检查会更有效。第一个有两个三位数因子的就是答案。

例如

  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;
  }

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;
  }
小瓶盖 2024-09-17 09:29:44

第一个回文应该是最大的,因为我是从顶部倒数

问题是您可能已经找到了大 i 和小 g 的回文。可能存在一个更大的回文,它是 jk 的乘积,其中:(

i > j and
g < k

我希望这是有道理的)。

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).

凌乱心跳 2024-09-17 09:29:44

Java实现:

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;
            }

     }

}

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;
            }

     }

}
长伴 2024-09-17 09:29:44

关于性能的一句话。您有可能复制许多产品,因为您使用的是非常简单的嵌套循环方法。例如,您从 999*999 开始,然后是 999*998,等等。当内循环结束时,您将递减外循环并再次从 998*999 开始,这与 999*998 相同。

实际上,您想要做的是使用与当前外循环值相同的值启动内循环。这将消除您的重复操作。像这样的东西......

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

但是,正如埃米利奥指出的那样,你认为你找到的第一个回文就是答案的假设是不正确的。显然,您需要首先计算最大的数字。所以你应该按这个顺序尝试它们; 999*999、999*998、998*998、999*997、998*997 等...

还没有测试过,但我认为你想要这样的东西(伪代码):

x = 999;
n = 0;

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

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

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
  }
}
西瑶 2024-09-17 09:29:44

上面提供的所有答案都非常好,但我仍然无法限制自己编写代码。 @thyrgle 发布的代码绝对完美。他需要做的只是稍微修正一下,检查哪个乘积是最大值。
代码可以是

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";

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";
月下伊人醉 2024-09-17 09:29:44
#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);

}
#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);

}
简单爱 2024-09-17 09:29:44
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)

它给出 906609 作为最大的回文数

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文