备忘。
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 }
早就忘了当时写这个是干嘛了。