求第N个回文数 模板

备忘。

 1 /*看到n可以取到2*10^9.说明普通方法一个个暴力计算肯定会超时的,那打表呢?打表我们要先写个打表的代码,这里不提供。打完表观察数据,我们会发现数据其实是有规律的。完全不需要暴力的把所有数据打出来了!
 2 通过数据我们发现,第n个回文数的规律如下:
 3 1位的回文数有9个
 4 2位的回文数有9个
 5 3位的回文数有90个
 6 4位的回文数有90个
 7 5位的回文数有900个
 8 6位的回文数有900个
 9 原因是什么呢,如四位数的回文数个数,我们只看字符串的一半,从1001到9999,只看一半就是共有90个回文数。
10 通过这样的规律,我们知道,只要数位增加2位,相应的该数位回文数就会是上位的10倍。
11 编码过程就是,先算出这个回文数有几位,然后算该位数下最小的回文数与该回文数的距离(回文数以一半为基准算)
12 时间复杂度几乎为O(1),而之前的循环判断回文数并记数的方法明显快。*/
13 #include<iostream>
14 #include<cstdio>
15 using namespace std;
16 typedef long long ll;
17 ll findhw(ll index){
18     ll res,cnt=0,w=0,num=9,half=1;
19     while(1){
20         if(w>0&&w%2==0)num*=10;
21         w++;
22         if(cnt+num>=index)break;
23         cnt+=num;
24     }
25     index=index-cnt-1;
26     for(int i=0;i<(w-1)/2;i++)
27         half*=10;
28     half+=index;
29     res=half;
30     if(w%2==1)half/=10;
31     while(half){
32         res=res*10+half%10;
33         half/=10;
34     }
35     return res;
36 }
37 int main(){
38     ll n;
39     while(~scanf("%lld",&n))
40         printf("%lld
",findhw(n));
41     return 0;
42 }

早就忘了当时写这个是干嘛了。

原文地址:https://www.cnblogs.com/ZERO-/p/9822495.html