如何有效地计算第n个n位回文?

时间:2012-08-12 20:59:34

标签: c++ c algorithm palindrome

我认为这个问题很容易理解。为了更加清晰,我举例说明:

在2位数的回文列表中,第7回文为77(第1回合为11,第2为22,依此类推)。

显然存在强力解决方案,但效率不高。

有人能建议我一些更好的解决方案吗?

5 个答案:

答案 0 :(得分:11)

首先,我们可以简化问题,因为我们只需要查看数字的前半部分(如果有奇数个数字则向上舍入)。我会将第一组数字称为有效数字,其余非有效数字

这是因为非重要数字必须与有效数字匹配(反之)。不可能有另一个回文数字具有相同的前导有效数字和不同的非有效数字。 有效数字确定整个回文数。

现在,我们只需要提出一种算法来生成第n个有效有效数字。如果我们允许前导零,这将更容易,因此我们将提出允许前导零的算法,然后调整算法。

前几个回文(有效数字)将是:

  • 1:0000
  • 2:0001
  • 3:0002
  • ...
  • 100:0099

所以我们可以通过找到(n-1)的十进制表示来找到第n个数字的有效数字。

要在不允许前导零的情况下调整算法以便工作,我们将以一个作为前导数字开始:

  • 1:1000
  • 2:1001
  • 3:1002
  • ...
  • 100:1099

这归结为找到(n-1)+ 1000 = n + 999的十进制表示并扩展为完整的回文

示例:找到长度为9的第113个回文。

  • 确定要查看的位数:向上舍入(9/2)= 5 - >只看前5位数。
  • 查找要添加以删除前导零的数字:10 ^(5-1)= 10000
  • 使用公式 :( 113 - 1)+ 10000 = 10112
  • 扩展到回文:101121101

另一方面,该算法也可以推广到找到任何有序符号集(或字母表)的第n个回文。

广义算法

鉴于:找到回文数 n ,回文符号 m 符号为数字,有 p 符号(十进制10个符号)

  • q =上限( m / 2)
  • 偏移 = p ^( q - 1)
  • 数字 =( n - 1)+ 偏移
  • 回答数字扩展为回文

答案 1 :(得分:5)

前几个7位回文是:

  • 1000001
  • 1001001
  • 1002001
  • 1003001
  • ...
  • 1009001
  • 1010101
  • 1011101
  • ...

我认为从 n th m -digit回文中的模式很容易看出......

答案 2 :(得分:2)

当位数为偶数时,从第100..0开始,只取第n个数字的一​​半,其中长度是数字的一半。回文就是这个数字,然后是它的镜子。

对于奇数个数字,只需取该数字的一半的上限,并以相同的方式从100 ... 0开始计数。然后回文就是这个数字,然后是镜子,第一个数字被删除了。

第65位数字:

65 + 9999 = 10064

1006446001

第10298位13位数:

10298 + 999999 = 1010297

1010297920101

答案 3 :(得分:0)

对于两位数的回文,两个连续回文之间的差异为11。

答案 4 :(得分:-3)

类似的东西:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;

void reverseString(char *dest,char *src){
 char *iter=src;
 while (*iter) iter++;
 while (iter!=src){
  iter--;
  *dest=*iter;
   dest++;
 }
 *dest=0;
}

char *pal(int n,int len){
  char *tmp=new char[len/2+2];
  char *out=new char[len+1];
  sprintf(out,"%i",n+int(pow(10.0,(len+1)/2-1))-1);
  reverseString(tmp,out); //copy reversed out into tmp
  strcat(out,tmp+len%2);
  delete []tmp;
return out;
}

int main(){
 cout<<pal(4,7)<<endl;
}