C 一个数字的最小基数,当以该基数表示时,该基数使其成为回文
给定一个整数C 一个数字的最小基数,当以该基数表示时,该基数使其成为回文,c,math,data-structures,C,Math,Data Structures,给定一个整数x,我必须找到一个最小基数b(b>1),这样x基数b就是回文 以5为底的2是回文,即以2为底的5:101是回文。如何以一种更好的方式解决它,而不是用暴力解决它?公平警告:这不是一个完整的答案,但有些注释可能有用。希望考虑到问题和评论的非正统性质,没有人会对此感到太不安。:) 基地2 11:3 101:5(+2)d 111:7(+2)2 1001:9(+2)d 1111:15(+6)2 10001:17(+2)d 10101:21(+4) 11011:27(+6)2 11111:3
x
,我必须找到一个最小基数b
(b>1),这样x
基数b
就是回文
以5为底的2是回文,即以2为底的5:101是回文。如何以一种更好的方式解决它,而不是用暴力解决它?公平警告:这不是一个完整的答案,但有些注释可能有用。希望考虑到问题和评论的非正统性质,没有人会对此感到太不安。:)
- 基地2
- 11:3
- 101:5(+2)d
- 111:7(+2)2
- 1001:9(+2)d
- 1111:15(+6)2
- 10001:17(+2)d
- 10101:21(+4)
- 11011:27(+6)2
- 11111:31(+4)
- 100001:33(+2)d
- 101101:45(+12)
- 110011:51(+6)2
- 111111:63(+12)
- 基数3
- 11:4
- 22:8(4)1
- 101:10(+2)d
- 111:13(升3)
- 121:16(升3)
- 202:20(4)1
- 212:23(+3)
- 222:26(+3)
- 1001:28(+2)d
- 1111:40(+12)
- 1221:52(+12)
- 2002年:56(+4)1
- 2112:68(+12)
- 2222:80(+12)
- 基地4
- 11:5
- 22:10(5)1
- 33:15(5)1
- 101:17(+2)d
- 111:21(升4)
- 121:25(+4)
- 131:29(+4)
- 202:34(5)1
- 212:38(+4)
- 222:42(+4)
- 232:46(+4)
- 303:51(+5)1
- 313:55(+4)
- 323:59(+4)
- 333:63(+4)
- 1:第一个数字在这里递增
- 2:第二个数字在这里递增(我只把这个标记为基数2;它似乎与其他地方无关)
- d:此处增加的位数(第一位数重置为1)
- 基中的第一个(最小)回文总是(基+1)。我们不允许1,也不允许任何前导零
- (N
- 第(base)个回文总是比第(base-1)个回文多2个(并且总是表示为101)
- 2位回文的数量为(以1为基数)
- 3位和4位回文的数量为(base-1)*base
- x的回文表示的位数为1+logu基(x)
- 给定长度的第一个回文总是10..01
- 当末尾没有标记时(即,当第一个数字和数字计数都保持不变),您可以看到重复差异的模式。这可能会让我们从10..01开始“快进”通过候选回文
- 对于子孙后代,这里有一个蛮力方法,从3到1000检查。您“只”需要从
2
到n-1
检查基数,因为从逻辑上讲,basen-1
中的n
始终是11
——它仍然是回文的最小可能基数
奇怪的是,只有数字3、4、6、11和19需要一直检查到11
。
多达1000个,有60个二进制回文,所以第一次尝试就可以找到这些回文
正如可以预料的那样,在基数36以上,它无法找到许多数字的回文
三个值得注意的重复值:
- 基
中的任何数字n
都是n^2+1
101
- 基
中的任何数字n-1
都是n^2
121
的所有结果似乎都适用于1[0*]1
x^n+1
int是回文(char*string)
{
int l=strlen(string),l2=(l+1)>>1,i=0;
而(i 对于(number=3;number这必须以蛮力的方式解决,但您可以通过对您的方法应用一些逻辑来避免使其成为蛮力搜索,从而消除一些候选者
例如,可以避免测试数字可整除的基数,从而保存基数转换过程和回文测试。原因很简单:任何基数中的表示形式都不能以零开头,这意味着该表示形式中的数字也不能以零结尾,否则将不会是回文
在基数x表示法中以零结尾的数字意味着该数字可与x整除,而无余数
此提示不能传递到其他数字,因为其余数字可以是该基数中可表示的任何数字
不幸的是,我不能想出任何其他的通用逻辑来排除候选。然而,我可以想出另一个逻辑,它将降低基数的上界来检查候选,然后可以肯定地说,答案就是简单的基数(x-1)
x的基数(x-1)产生11
作为表示,这是一个回文。随着基数的减少,表示中的数字变大,或者我们得到更多的数字
- base
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之间的情况类似,但di
/*
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
#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;
}