CodeChef K2 Palindromic Numbers(进制)

来源:互联网 发布:怎么查看手机端口号 编辑:程序博客网 时间:2024/06/04 19:23

Palindromic Numbers

Problem Code: K2

Johnny has figured out that there are some numbers which have an interesting property: they are the same when read from left to right, and from right to left. For example, 5115 and 929 are such numbers, while 31 and 125 are not. Johnny calls such numbers palindromic numbers.

After a while, Johnny has realized that his definition of palindromic numbers is not really precise. Whether a number is palindromic or not depends on the base in which the number is written. For example, 21 is not palindromic in base 10 but it is palindromic in base 2 (because 21 = 101012).

Johnny finds it interesting that any number becomes palindromic when it is written in an appropriate base.

Given a number N, write a program to help Johnny compute the smallest base B such that N is palindromic when written in base B.

Input

The first line contains t, the number of test cases (about 1000). Then t test cases follow.

Each test case consists of a number N written in one line (1 <= N <= 1010).

Output

For each given number N, print a line containing the smallest base B such that N is palindromic in base B.

Example

Input:31421Output:232



        看到这题是否有一些似曾相识的感觉……

        当时的校赛,题目比这个简单一些,就是求满足在一个进制下全部是1,而这次是在一个进制下是回文数。

        有了之前那道题的铺垫,我们很容易的可以解决第一部分的问题,那就是对于1~sqrt(n)的进制,我们可以直接枚举然后判断是否是回文数,复杂度O(N^0.5)。问题是,如果在这一范围里面进制都不满足的时候怎么办。进制大于sqrt(n)意味着在答案所在的进制下,数字只有两位,而且两位要完全相等。直接枚举进制是肯定不行的,然后这题也不像校赛那题那样有单调性,所以得另寻他法。

        我们知道,进制不能再往上枚举了,因为会TLE,那么能不能再往下枚举什么东西呢?由于进制大于sqrt(n),所以很显然,最后这两位数字要相等肯定不能大于sqrt(n),于是我们不妨枚举最后两位相同数字的大小。我们从sqrt(n)-1开始枚举两位数字的大小,一直到1(1一定有解),判断对应大小下是否有满足条件的进制可选,第一个满足条件的进制就是最后答案。至于判断也不太难想,因为只有两位,那么一定有b*(q+1)==n,其中b是我们枚举的数字大小,而q是最后的答案进制。显然,我们要满足n%b==0,然后诱因为q进制下有b出现,所以b<=q,满足这两条就能够保证存在这样一个进制。

        如此下来,此题的时间复杂度就是O(N^0.5)非常的完美,具体见代码(原网站上有其他人的代码,自我感觉他们写的晦涩难懂):

#include<bits/stdc++.h>#define LL long longusing namespace std;LL num[100],n;int palindromic(LL b,LL x)//暴力判断b进制下x是否是回文数{    int tot=0;    while(x)    {        num[++tot]=x%b;        x/=b;    }    for(int i=1;i<=tot/2;i++)        if (num[i]!=num[tot-i+1]) return 0;    return 1;}long long smallest_base(LL x){    LL b,q;    if (x==1||x==3) return 2;    if (x==2||x==4) return 3;    for(b=2;b*b<=x;b++)        if (palindromic(b,x)) return b;//暴力判断2~sqrt(n)    b--; while (x%b||x/b<=b+1) b--;//枚举最后两位上的数字,看是否有满足条件的进制    return x/b-1;}int main(){    int T_T;    cin>>T_T;    while(T_T--)    {        scanf("%lld",&n);        printf("%lld\n",smallest_base(n));    }    return 0;}