Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 一个数字的最小基数,当以该基数表示时,该基数使其成为回文_C_Math_Data Structures - Fatal编程技术网

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)
我将与之前的差异标记为(+n),并在末尾添加了一些注释:

  • 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
      检查基数,因为从逻辑上讲,base
      n-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;
      }