欧拉计划第4题

Problem 4:

        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.

问题4

        回文数两个方向读得到的是同一个数。由22位数相乘得到的最大的回文数是9009=91*99

        找出由23位数相乘得到的最大的回文数。

分析:

        思路1:遍历所有3位数的积,找出最大的回文数。[优点:简单,易快速实现。缺点:效率低。]

        思路2:外循环由999向下遍历,内层只遍历大于等于外循环的数,计算乘积找出最大回文数。[优点:较思路1速度有提升]

        思路3:如果使用32int值,则思路2只能计算到24位数的最大回文数,为最大限度利用int值,对是否是回文数的判断采用以下方法:

根据乘法特点(被乘数的每1位分别乘以乘数,并将结果相加即可求出乘积),只需将被乘数的每1位乘以乘数,并将结果相加即可求出相应位的乘积值,因此可以用乘数的每1

位分别乘以被乘数,每求出1位数字将结果除以10

                                    5 4 3 2 5

                    *              5 4 3 2 5

                ------------------------------

                                2 7 1 6 2 5

                             1 0 8 6 5 0

                         1 6 2 9 7 5

                 -------------------------------

                                          6 2 5

思路3程序如下:

解:

#define __METHOD_3
//#define __METHOD_2

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <malloc.h>
#include <algorithm>

using namespace std;

#define PRINT       printf
#define DPRINT      printf
#define BOOL        bool
#define TRUE        true
#define FALSE       false
#define MAX_RES_BUF	21

typedef int         INT;
typedef void        VOID;
typedef char        CHAR;

#ifdef __METHOD_3
BOOL IsPalindromic(INT i, INT j, CHAR *szRes, INT len)	//是回文数则返回TRUE,szRes返回该回文数
{
	if (NULL == szRes)
		return FALSE;

	//计算乘积
	INT num, k;
	k = 0;
	num = 0;
	while ( j > 0)
	{
		num += i * (j % 10);
		if (k >= len)
			return FALSE;
		szRes[k++] = num % 10 + '0';
		j /= 10;
		num /= 10;
	}
	while (num > 0)
	{
		szRes[k++] = num % 10 + '0';
		num /= 10;
	}
	szRes[k] = '\0';

	//反转串并比较
	CHAR *szRev;
	szRev = (CHAR *)malloc(sizeof(CHAR)*(k+1));	
	strcpy(szRev, szRes);
	reverse(szRes, szRes+k);
	if (0 == strcmp(szRes, szRev))	//是回文数?
	{
		free(szRev);
		return TRUE;
	}

	free(szRev);

	return FALSE;
}

BOOL MaxPalindromic(INT num, CHAR *szRes, INT len)	//szRes返回2个num位数字相乘的最大回文数
{
	if (NULL==szRes || num <= 0 || num>8)
		return FALSE;

	INT min, max;
	min = (int)pow(10, num-1);
	max = min * 10 - 1;

	INT i, j;
	CHAR buf[MAX_RES_BUF];	//结果(回文数)

	memset(szRes, 0, len);
	for (i=max; i>=min; i--)
		for (j=max; j>=i; j--)
		{
			if (IsPalindromic(i, j, buf, MAX_RES_BUF))
			{
				if (strlen(buf) > strlen(szRes))
				{
					if (strlen(buf) >= len)
						return FALSE;
					strcpy(szRes, buf);
				}
				else if (strlen(buf) == strlen(szRes))
				{
					if (strcmp(buf, szRes) > 0)
					{
						if(strlen(buf) >= len)
							return FALSE;
						strcpy(szRes, buf);
					}
				}
			}
		}

	return TRUE;
}
#endif

#ifdef __METHOD_2
BOOL IsPalindromic(INT n)	//n是回文数则返回TRUE
{
	INT nRev;
	INT nTem;

	nTem = n;
	nRev = 0;
	while(nTem > 0)
	{
		nRev = nRev * 10 + (nTem % 10);
		nTem /= 10;
	}

	if(nRev == n)
		return TRUE;
	
	return FALSE;
}

INT MaxPalindromic(INT num)	//返回2个num位数字相乘的最大回文数
{
	if (num <= 0)
		return -1;

	INT min, max;
	min = (int)pow(10, num-1);
	max = min * 10 - 1;

	INT i, j;
	INT res;
	INT n;

	res = -1;
	for (i=max; i>=min; i--)
		for (j=max; j>=i; j--)
		{
			n = i * j;
			if (n>res && IsPalindromic(n))
				res = n;
		}

	return res;
}
#endif

INT main(INT argc, CHAR *argv[])
{
	INT num;
#ifdef __METHOD_3
	CHAR szRes[MAX_RES_BUF];
	while (1)
	{
		PRINT("请输入数字位数(1~8),输入负数退出:\n");
		scanf("%d", &num);

		if (num < 0)
			break;

		MaxPalindromic(num, szRes, MAX_RES_BUF);
		PRINT("%s\n", szRes);
	}


#endif


#ifdef __METHOD_2
	INT res;
	while (1)
	{
		PRINT("请输入数字位数(1~4),输入负数退出:\n");
		scanf("%d", &num);

		if (num < 0)
			break;

		res = MaxPalindromic(num);
		PRINT("%d\n", res);
	}
#endif
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值