找到两个三位数字产品的最大回文问题

时间:2010-07-14 22:07:44

标签: c algorithm palindrome

所以在Project Euler上,Problem 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. 第一个回文应该是最重要的回归,因为我从顶部倒计时。
  6. 现在让我解释一下我的支票:

    1. 首先关闭,因为这是两个三位数相乘,以确定一个char需要保持该值的大小我去了一个计算器并乘以999 * 999然后它最终为6然后我需要添加一个因为我从一个问题中找到了我之前发布的问题sprintf最后放了一个\0字符。
    2. 好的,现在我有一个字母和全部,我复制了resulti*g中的int main)并将其放入char b[7]
    3. 然后我只是通过硬编码我需要检查的每个插槽来检查b以查看它是否与自己相等。
    4. 然后我相应地返回,1为真,2为假。
    5. 这对我来说似乎是完全合乎逻辑的,但它并不适用于一些奇怪的原因。任何提示?

10 个答案:

答案 0 :(得分:13)

这个假设是错误的:

  

自从我从顶部开始倒数时,第一个回文应该是最大的回文。

你会在999*100 = 99900之前检查998*101 = 100798,所以显然你不能指望它。

答案 1 :(得分:2)

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

只是一个例子:

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

第一个较小,但由于您首先在i上进行迭代,然后在g上首先进行迭代。

好吧,他们不是回文,但概念是一样的..

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

  

第一个回文应该是最重要的回归,因为我从顶部算起来

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

i > j and
g < k

(我希望这是有道理的)。

答案 4 :(得分:1)

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

     }

}

答案 5 :(得分:0)

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

真的,你要做的是用与当前外循环值相同的值启动内循环。这将消除您的重复操作。像这样......

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

然而,正如Emilio指出的那样,你认为你找到的第一个回文将是答案是不正确的。显然,你需要先计算出最大的数字。所以你应该按照这个顺序尝试它们; 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
  }
}

答案 6 :(得分:0)

我发现这可能对你有帮助article。它改进了蛮力方法。

答案 7 :(得分:0)

以上提供的所有答案都非常出色,但我仍然无法限制自己编写代码。 @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";

答案 8 :(得分:0)

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

}

答案 9 :(得分:0)

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作为最大的回文数