![](/img/trans.png)
[英]Finding largest palindrome from product of two 3 digit numbers (Project Euler problem)
[英]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
開始的程序:
int i
和int g
是我的乘數。 它們是那兩個三位數的數字。 int final
是將存儲最大回文數的數字。 現在讓我解釋一下我的支票:
sprintf
在末尾添加了\\0
字符。 result
(在int main
i*g
)並將其放在char b[7]
。 b
是否與自身相等。 對我來說,這似乎是完全合乎邏輯的,但是由於某些奇怪的原因,它不起作用。 有什么提示嗎?
這個假設是錯誤的:
自從我從頭開始遞減計數以來,第一個回文應該是最大的回文。
您將在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
的回文。 j
和k
的乘積可能有較大的回文,其中:
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.