求两个三位数乘积的最大回文问题
Posted
技术标签:
【中文标题】求两个三位数乘积的最大回文问题【英文标题】:Finding the largest palindrome of the product of two three digit numbers problem 【发布时间】:2010-07-14 22:07:43 【问题描述】:所以在 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
开始解释我的程序:
int i
和 int g
是我的乘数。它们就是那两个三位数。
int final
是存储最大回文数的数字。
我开始了两个 for 循环,以获取每个数字的可能性。
当到达第一个回文时,我使用 goto 退出循环(可能不应该,但它不会对这样的小程序产生太大影响)。
第一个回文应该是最大的回文,因为我从顶部倒数。
现在让我解释一下我的支票:
-
首先,因为这是两个三位数相乘以确定一个 char 保持该值所需的大小,所以我用计算器乘以 999 * 999,结果是 6,然后我需要加一个因为我从我之前发布的一个问题中发现
sprintf
在末尾添加了一个\0
字符。
好的,既然我有一个字符,我复制了result
(int main
中的i*g
)并将其放入char b[7]
。
然后我检查了b
,通过硬编码我需要检查的每个插槽来查看它是否与它自己相同。
然后我相应地返回,1 为真,2 为假。
这对我来说似乎完全合乎逻辑,但是由于某些奇怪的原因它不起作用。有什么提示吗?
【问题讨论】:
你的“g”倒计时太快了——你可能会发现一个基于 999 * 101 的回文,但真正的答案更像是 997 * 867,它更大。 一个提示:乘法是可交换的,因此您可以使用for (g = i; g > 99; g--)
来避免同时测试999*100
和100*999
。
顺便说一句,这是 goto 的合法用途
解决这个问题的另一种方法是从 999*999 迭代到 100*100,然后对每个回文测试看它是否是两个 3 位数字的乘积。
【参考方案1】:
这个假设是错误的:
第一个回文应该是最大的一个,因为我从顶部倒数。
你会在998*101 = 100798
之前检查999*100 = 99900
,所以显然你不能指望它。
【讨论】:
【参考方案2】:问题是你找到的第一个回文肯定不是更大的。
只是一个例子:
i = 900, g = 850 -> 765000
i = 880, g = 960 -> 844800
第一个较小,但由于您首先在 i
上进行迭代,然后在 g
上将首先发现它。
好吧,它们不是回文,但概念是一样的..
【讨论】:
【参考方案3】:我认为您正在从头到尾解决这个问题。从最高到最低生成回文然后通过分解它们来检查会更有效。第一个有两个三位数的因素就是答案。
例如
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】:第一个回文应该是最大的,因为我是从上往下倒数
问题是您可能找到了一个大的i
和一个小的g
的回文。 j
和 k
的乘积可能存在更大的回文,其中:
i > j and
g < k
(我希望这是有道理的)。
【讨论】:
【参考方案5】: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;
【讨论】:
【参考方案6】:关于性能的一句话。您有可能复制许多产品,因为您使用的是非常简单的嵌套循环方法。例如,你从 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
【讨论】:
【参考方案7】:我发现这个article 可能会对你有所帮助。它改进了蛮力方法。
【讨论】:
【参考方案8】:以上提供的所有答案都非常好,但我仍然无法限制自己编写代码。 @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";
【讨论】:
尽量不要拼错用户名(如 thyrgle)。尝试添加一些东西,比如不要摸索已知太小的产品:maxPalin = 100001 ... for (int lowerBound = maxPalin/i, j = i ; lowerBound <= j ; j--)
【参考方案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)
它给出了 906609 作为最大的回文数
【讨论】:
以上是关于求两个三位数乘积的最大回文问题的主要内容,如果未能解决你的问题,请参考以下文章