算法竞赛入门经典:第七章 暴力求解法 7.4双基回文数

/*
双基回文数:
如果一个正整数n至少在两个不同的进位制b1和b2下都是回文数(2<=b1,b2<=10),则称n是双基回文数(注意,回文数不能包含前导0)。输入正整数S<10^6,输出比
S大的最小双基回文数>
输入:1600000(1632994)
输出:1632995

思路:
1对比S大每个数进行2到10进制的罗列,这8种中但凡有两种进制回文数相同,就输出
2判断回文数做成一个函数,将一个数先分解(从个位到最高位)存放在一个数组,对这个数组的前一半与后一半进行比较,相同,则认为是回文数
*/

/*
关键:
1 int iMark[11] = {0};//默认标记数组iMark[i]=1表示i进制是回文数,这里进制最大为10,因此iMark必须为11
2 for(p = 0,q = j-1; p < j/2;)//注意这里的j是数组的最后一位,q必须从j-1开始
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSIZE 1024


bool isEchoNum(int n,int *iMark)
{
	for(int b = 2 ;  b <= 10; b++)
	{
		int iArr[MAXSIZE];
		int k = n;
		int j = 0;
		//分解这个数
		do{
			iArr[j++] = k % b;
			k /= b;
		}while(k);
		//判断回文
		int p,q;
		bool isEcho = true;
		for(p = 0,q = j-1; p < j/2;)//注意这里的j是数组的最后一位,q必须从j-1开始
		//for(p = 0,q = j;p <= (j-1)/2;)
		{
			if(iArr[p++] != iArr[q--])
			{
				isEcho = false;
			}
		}
		if(isEcho == true)
		{
			iMark[b] = 1;
		}
	}
	//判断是不是达到至少两次进制回文
	int iCount = 0;
	for(int m = 2; m <= 10; m++)
	{
		if(iMark[m])
		{
			iCount++;
		}
	}
	if(iCount >= 2)
	{
		return true;
	}
	else
	{
		return false;
	}
}

void doubleBaseEchoNum(int n)
{
	if(n >= 1e7)
	{
		return;
	}
	for(int i = n + 1; ; i++)
	{
		int iMark[11] = {0};//默认标记数组iMark[i]=1表示i进制是回文数,这里进制最大为10,因此iMark必须为11
		memset(iMark,0,sizeof(iMark));
		if(isEchoNum(i,iMark))
		{
			printf("%d\n",i);
			break;
		}
	}
}

int main(int argc,char* argv[])
{
	int n;
	scanf("%d",&n);
	doubleBaseEchoNum(n);
	system("pause");
	return 0;
}

你可能感兴趣的:(算法竞赛)