回文数
描述
回文数字是指一个数字是左右对称的。比如1221,121这种,左右两边的数字反转之后依旧保持一样的数字叫做回文数字。Peter有一个幸运数字是6,他现在想要知道对于某一个数字,比这个数字大的所有回文数字当中,第6小的回文数字是多少。由于Peter的话很多,所以他可能会问很多次。
输入
首先,输入一个数字q,表示Peter询问的次数。(1<=q<=1e4)
然后,对于每一次询问,输入一个数字x,表示询问的数字。(0<=x<=1e9)
输出
对于每一次询问,你需要输出比给定的数字的大的所有回文数字里面,第6小的回文数字是多少。
输入样例 1
2
1
11
输出样例 1
7
77
提示
样例解释,询问两次,第一次询问比1大的所有回文数字里面,第6小的数字,我们发现,在1后面的回文数字依次是2,3,4,5,6,7,8,9,11......,其中7是第6小的。所以答案就是7;第二次询问比11大的所有回文数字里面,第6小的数字,我们发现,在11后面的回文数字依次是22,33,44,55,66,77,88,99......,其中77是第6小的。所以答案就是77.
巧妙点:upper_bound()的使用
upper_bound() 算法会在前两个参数定义的范围内查找大于第三个参数的第一个元素。对于这两个算法,它们所查找的序列都必须是有序的,而且它们被假定是使用 < 运算符来排序的。eg. int pos = upper_bound(a,a+cnt,x)-a;
upper_bound( begin,end,num,greater<type>() ):从数组的begin位置到end-1位置二分查找第一个小于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
(1)暴力枚举:将所有数都存储起来,然后找时用upper-bound函数找出下标,再输出在它后面的第5个数字
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
ll a[maxn],cnt=0;
int main(){
//1
for(int i=1;i<10;i++){
a[++cnt]=i;
}
//2
for(int i=1;i<10;i++){
a[++cnt]=i*10+i;
}
//3
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
a[++cnt]=i*100+j*10+i;
}}
//4
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
a[++cnt]=i*1000+j*100+j*10+i;
}
}
//5
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
a[++cnt]=i*10000+j*1000+k*100+j*10+i;
}
}
}
//6
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
a[++cnt]=i*100000+j*10000+k*1000+k*100+j*10+i;
}
}
}
//7
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
for(int m=0;m<10;m++){
a[++cnt]=i*1000000+j*100000+k*10000+m*1000+k*100+j*10+i;
}
}
}
}
//8
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
for(int m=0;m<10;m++){
a[++cnt]=i*10000000+j*1000000+k*100000+m*10000+m*1000+k*100+j*10+i;
}
}
}
}
//9
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
for(int m=0;m<10;m++){
for(int n=0;n<10;n++){
a[++cnt]=i*100000000+j*10000000+k*1000000+m*100000+n*10000+m*1000+k*100+j*10+i;
}
}
}
}
}
//10
for(int i=1;i<10;i++){
for(int j=0;j<10;j++){
for(int k=0;k<10;k++){
for(int m=0;m<10;m++){
for(int n=0;n<10;n++){
a[++cnt]=i*1000000000+j*100000000+k*10000000+m*1000000+n*100000+n*10000+m*1000+k*100+j*10+i;
}
}
}
}
}
int q;
cin>>q;
while(q--){
ll x;
cin>>x;
int pos = upper_bound(a,a+cnt,x)-a;
cout<<a[pos+5]<<endl;
}
return 0;
(2)找规律:打表,二分
}