簡體   English   中英

尋找兩個三位數的乘積最大的回文數問題

[英]Finding the largest palindrome of the product of two three digit numbers problem

因此,在歐拉計畫上, 問題4陳述如下:

回文數在兩個方向上都相同。 由兩個兩位數的乘積組成的最大回文數為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. 首先,因為這是兩個三個數字相乘,以確定一個char要保持該值所需的大小,所以我去了一個計算器並乘以999 * 999,結果為6,然后我需要加一個,因為我發現從我之前發布的問題中, sprintf在末尾添加了\\0字符。
  2. 好的,現在我有了一個char和全部,我復制了result (在int main i*g )並將其放在char b[7]
  3. 然后,我通過對需要檢查的每個插槽進行硬編碼來檢查b是否與自身相等。
  4. 然后我相應地返回了,1表示正確,2表示錯誤。

對我來說,這似乎是完全合乎邏輯的,但是由於某些奇怪的原因,它不起作用。 有什么提示嗎?

這個假設是錯誤的:

自從我從頭開始遞減計數以來,第一個回文應該是最大的回文。

您將在998*101 = 100798之前檢查999*100 = 99900 ,因此顯然您不能指望這一點。

問題在於,您確定的第一個回文肯定不是更大的回文。

只是一個例子:

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

第一個較小,但是由於您首先在i上進行迭代,然后在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;
  }

自從我從頭開始遞減計數以來,第一個回文應該是最大的回文

問題是您可能已經找到了一個大i和小g的回文。 jk的乘積可能有較大的回文,其中:

i > j and
g < k

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

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

     }

}

上面提供的所有答案都是極好的,但是我仍然不能限制自己編寫代碼。 @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";
#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);

}

關於性能的一句話。 您可能會復制許多產品,因為您使用的是非常簡單的嵌套循環方法。 例如,從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
  }
}
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作為最大回文數

我發現這篇文章可能會對您有所幫助。 它改進了蠻力方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM