给定一个整数x
,我必须找到最小基数 b
(b> 1),以便x
基础 b
是回文。
答案 0 :(得分:4)
公平警告:这不是一个完整的答案,而是一些可能有用的注释。希望到目前为止,问题和评论具有非正统性,没有人会对此感到不安。 :)
我将之前的差异标记为(+ n),最后添加了一些注释:
一些结构性观察:
最后,一些欠发达的想法:
答案 1 :(得分:4)
这必须以粗暴的方式解决,但你可以通过在你的方法中应用一些逻辑来避免使它成为一种蛮力搜索,从而消除一些候选人。
例如,您可以避免测试数字可被整除的碱基,从而节省碱基转换过程以及回文测试。原因很简单:在任何基数中的表示可能不以零开头,这意味着数字也不会以该表示中的零结束,否则不会是回文。
在基础 x 表示中以零结尾的数字表示该数字可以用 x 整除,而不会有余数。
此提示不能转移到其他数字,因为休息可以是在该基础中可表示的任何内容。
不幸的是,我无法提出任何其他通用逻辑来消除候选人。但是,我可以想出另一个会降低基数的上限以检查候选者,之后可以肯定地说答案只是基础(x - 1) x 。
x 的基础(x - 1)产生11
作为表示,这是一个回文。随着基数减少,表示中的数字变得更大,或者我们得到更多的数字。
2
中的下一个最小的回文将是101
2
的基数中的下一个最小的回文将是22
让我们从反向检查,从顶部开始:
for (int base = x - 1; base >= 2; base--)
// is x represented palindromic at base (base)
想象一下这对于一个大的 x 。答案最初将是是,然后我们将在很长一段时间内开始否。这是为什么?让我演示一下:
/*
base representation
x - 1 11
x - 2 12
x - 3 13
x - 4 14
...
x - n 1n
...
x-x/2 20 or 21 for x even or odd
x / 2 20 or 21 for x even or odd
直到 x / 2 ,第二个数字(从最后一个)将保持不变,第一个数字将逐个缓慢增加。
在 x / 2 和 x / 3 之间类似,但这两者之间的差异更小(x / 6与x / 2相比) ,以及第一个数字将开始逐两增加;因此,将这种逻辑应用于其余部分变得越来越不重要。
好的,出于这个原因,除了小于6
的数字之外,如果我们碰巧找不到任何小于(x / 2)的基数,那么对于数字 x 的回文表示,我们可以安全地放弃并说答案是(x - 1)。
所有这些文字,只解释了两个可以实施的简单逻辑,以防止多余的测试:
最后一次讨论:如果主题在不同的基础上表示,为什么受到任何字母表中字母的限制?特别是当我们在电脑上工作时?只需使用整数数组,每个元素用数字正确表示数字,而不是任何字母或其他任何东西。就像字符串一样,可以使用终止值,可以是-1
。计算机可能要容易得多,因为无论如何它都不会来回转换成字母。
这是一个源代码,它完成了我上面解释的内容:
#include <stdio.h>
#include <malloc.h>
int ispalindrome(const int * string)
{
int length = 0;
while (string[length] != -1)
length++;
for (int i = 0; i < length / 2; i++)
{
if (string[i] != string[length - 1 - i])
return 0;
}
return 1;
}
int * converttobase(int number, int base)
{
int length = 0;
int temp = number;
while (temp)
{
length++;
temp /= base;
}
int * result = calloc(length + 1, sizeof * result);
for (int i = length - 1; i >= 0; i--)
{
result[i] = number % base;
number /= base;
}
result[length] = -1;
return result;
}
int lowestpalindromebase(int number)
{
int limit = (number < 6) ? (number + 2) : (number / 2);
// if number is more than or equal to 6, limit candidates with the half of it
// because, reasons...
for (int base = 2; base < limit; base++)
{
if (number % base) // number does have a remainder after division with base
{
int * converted = converttobase(number, base);
if (ispalindrome(converted))
{
free(converted);
return base;
}
free(converted);
}
}
return number - 1;
}
int main( )
{
for (int i = 1; i < 60; i++)
{
printf("%2d is palindromic at base %d\n", i, lowestpalindromebase(i));
}
return 0;
}
答案 2 :(得分:1)
对于后人来说,这是一种蛮力的方法,检查从3到1000.你只是&#39;必须检查从2
到n-1
的基数,因为基数n
中的n-1
始终是11
- 它可能是11
的最小基数。仍然是回文。
奇怪的是,只有数字3,4,6,11和19需要一直检查n^2 + 1
。
最多1000个,有60个二进制回文,所以这些都是在第一次尝试时找到的。
正如可以预料的那样,在基数36之上,它无法找到许多数字的回文。
两个三个值得注意的重复值:
n
中的任何数字101
均为n^2
。n-1
中的任何数字121
均为1[0*]1
。x^n+1
的所有搜索结果似乎都是int is_palindrome (char *string)
{
int l = strlen(string), l2 = (l+1)>>1, i = 0;
while (i < l2)
{
if (string[i] != string[l-1-i])
return 0;
i++;
}
return 1;
}
int main (void)
{
char buf[256];
int number, base, check;
int per_base[36] = { 0 };
for (number=3; number<=1000; number++)
{
check = 0;
for (base=2; base<=min(36,number-1); base++)
{
itoa (number, buf, base);
if (is_palindrome (buf))
{
check++;
per_base[base]++;
printf ("%d in base %d is %s\n", number, base, buf);
break;
}
}
if (!check)
printf ("%d is not a palindrome in anything up to 36\n", number);
}
for (number=2; number<36; number++)
printf ("%d-ary palindromes: %d\n", number, per_base[number]);
return 0;
}
。{{1}}