NOJ1046第K回文数——???
2014-06-10 22:29
211 查看
第K回文数
Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByteTotal Submit:612 Accepted:150
Description
回文数是这样一个正整数:它从左往右读和从右往左读是一样的。例如1,111,121,505都是回文数。将1到100,000,000内所有回文数按从小到达排序后,第k个回文数是多少呢?
Input
第一行为一个整数N,表示询问的次数。以下N行每行一个整数k,表示询问第k个回文数是多少。
Output
输出共N行,按照输入数据的顺序,依次输出第k个回文数。
Sample Input
2
5
10
Sample Output
5
11
Source
NUAA
分析:找规律。
1位数中回文数有9个:1,2,3,4,5,6,7,8,9
2位数中回文数有9个:11,22,33,44,55,66,77,88,99
3位数中回文数有90个:101,111,121,131,141,151,161,171,181,191;202,212,222。。。;909,919,929,939,949,959,969,979,989,999。
4位数中回文数有90个
。。。
相邻的位数中的回文数个数相同,且是10倍递增的。其次,同一位数里面的回文数的增长也是有规律的。如:101,111,121,131。。。
如果直接求出回文数存在数组里。莫名其妙的Wrong Answer!
下面给出比较好的写法,运行时间为0MS:
如k=224时,第K回文数为12521。先求出第K回文数的位数,再求出该数的左半边,因为对称,再求出右半边。(注意位数为奇数的情况)。最终的结果即为答案。
有意思的是:k减去每个位数的回文数的时候,如k-9-90-90-900-900。。。当k继续减位数时,k<0 那么就能确定第K回文数的个数,同时,这个回文数的左半边的除最高位之外的数也确定了。举例:
如k=224时,k-10-10-90-90>0,再减去900就小于0了,所以确定第224个回文数是5位数。同时,这个数的左半边的位数也能确定为3((5+1)/2)。且这个数的左半边是从100(因为左半边为3位)开始的第(k-10-10-90-90-1)个数。
所以这个数的左半边能确定了,实际即为100+25=125。
接下去的任务就是对称把右半边求出来。再整合即得到答案ans。这边的求右半边的数的写法比较nice!
反过来,如果给定12521,求它是第几个回文数,解法应该为:
解:因为12521为5位数,所以在它之前有9+9+90+90个数。12521在5位数中是10+10+6个。(0 1 2 3 4 5)
所以12521为第(9+9+90+90+10+10+6)= 224 个。
#include<stdio.h> //第K回文数 void fun(int k) { int half_len, left, weishu, num, ans = 0; num = 9; // 几位数对应多少回文数 1-9,2-9,3-90,4-90... for(weishu=1;k-num>0;weishu++) // 有几位,1开始 求出第k个回文数的位数 { // 对应的回文数 > k k -= num; if(weishu % 2 == 0) // 1位-9个,2位-9个,3-90,4-90...每2个增量为10倍 num *= 10; } half_len = (weishu+1) / 2; // 回文数的位数的一半,如12521为3 left = 1; // 回文数的左边一半,如12521中的125 for(int i=2;i<=half_len;i++) left *= 10; left += k-1; // 125 ans += left; // 125 if(weishu % 2 != 0) // 位数为奇数,左半边比右半边多一位 left /= 10; // 12 while(left) { ans = ans*10 + left%10; // (125*10+2)*10+1 left /= 10; } printf("%d\n",ans); } int main() { int n, k; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&k); fun(k); } return 0; }
还有一种比较清晰但是略烦的写法:
#include<stdio.h> int main() { int n,j,i,k; scanf("%d",&n); while(n--) { scanf("%d",&k); if(k <= 9) ; else if(k <= 18) k=(k-10)*11+11; else if(k <= 108) k=((k-19)/10+1)*101+(k-19)%10*10; else if(k <= 198) k=((k-109)/10+1)*1001+(k-109)%10*110; else if(k <= 1098) k=((k-199)/100+1)*10001+(k-199)/10%10*1010+(k-199)%10*100; else if(k <= 1998) k=((k-1099)/100+1)*100001+(k-1099)/10%10*10010+(k-1099)%10*1100; else if(k <= 10998) k=((k-1999)/1000+1)*1000001+(k-1999)/100%10*100010+(k-1999)%10*1000+(k-1999)/10%10*10100; else if(k <= 19998) k=((k-10999)/1000+1)*10000001+(k-10999)/100%10*1000010+(k-10999)/10%10*100100+(k-10999)%10*11000; printf("%d\n",k); } }
最后一种写法,一开始就把所有的回文数求出来,按从小到大排好序。但是提交Wrong Answer!???
#include<iostream> #include<algorithm> using namespace std; int cmp(const void *a,const void *b) { return *(int *)a-*(int *)b; } int a[10000000]; int main() { int n, m, i = 0, d1, d2, d3, d4, d5; for(d1 = 1; d1 <= 9; d1++) { a[i++] = d1; } for(d1 = 1; d1 <= 9; d1++) { a[i++] = d1*10+d1*1; } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { a[i++] = d1*100+d2*10+d1*1; } } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { a[i++] = d1*1000+d2*100+d2*10+d1*1; } } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { for(d3 = 0; d3 <= 9; d3++) { a[i++]= d1*10000+d2*1000+d3*100+d2*10+d1*1; } } } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { for(d3 = 0; d3 <= 9; d3++) { a[i++] = d1*100000+d2*10000+d3*1000+d3*100+d2*10+d1*1; } } } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { for(d3 = 0; d3 <= 9; d3++) { for(d4 = 0; d4 <= 9; d4++) { a[i++] = d1*1000000+d2*100000+d3*19999+d4*1000+d3*100+d2*10+d1*1; } } } } for(d1 = 1; d1 <= 9; d1++) { for(d2 = 0; d2 <= 9; d2++) { for(d3 = 0; d3 <= 9; d3++) { for(d4 = 0; d4 <= 9; d4++) { a[i++] = d1*10000000+d2*1000000+d3*100000+d4*10000+d4*1000+d3*100+d2*10+d1*1; } } } } qsort(a,i,sizeof(int),cmp); scanf("%d", &n); while(n--) { scanf("%d", &m); printf("%d\n",a[m-1]); } return 0; }
相关文章推荐
- 1046-第K回文数
- 第k回文数
- NOJ 1046 第K回文数 水题
- noj 1046 第K回文数
- 线性选择 求n个数中第k小数
- algrothm_逆序输出,回文(找中点+换位置)
- 判断一个字符串是否为回文的非递归算法
- 回文树学习小结
- C# 判定回文序列 中软面试
- 最长回文子串(转载自网易博客:鼻子很帅的猪)
- 找出文件中的回文
- 回文字符串(nyoj_37)
- Algorithm backup ---- Find the kth largest number(寻找第K大数)
- [HDOJ2639]Bone Collector II(第k优01背包)
- 回文
- java判断字符串是否回文
- 找第K大数的一些小算法技巧;
- HDU 3068 [最长回文子串]
- 找出第K大数(前K大数)的类快排思想总结...
- [USACO1.5]回文质数 Prime Palindromes