你是一个bilibili的六级号,由于经常一键三连,所以一个硬币都没有,现在你又做了个梦,在梦中你制定了一个硬币增加规则:
第一天登陆后硬币总数1个,第二天登陆后硬币总数112个,第三天登陆硬币总数112123个…,以此类推,梦中不知日月,你瞬间拥有了11212312341234512345612345671234567812345678912345678910123456789101112345678910…无穷多个硬币。
常年维护B站秩序的百漂怪看不下去了,决定随机挑一个数x,作为这个无穷数的第x位,如果你能正确答对这第x位上的数是什么,就赠送给你与这个数等量的硬币。
百漂怪总共会挑t次。
你决定编程模拟一下,搏一搏,单车变摩托。
输入格式:
第一行包含一个正整数t(1≤t≤10),表示百漂怪挑了t次。 接下来t行,每行一个正整数x (1 ≤ x≤ 2^31-1),表示第i次,百漂怪挑的是第x位。
输出格式:
输出共t行,每行输出对应第x位上的数。
输入样例1:
2
3
8
输出样例1:
2
2
输入样例2:
6
222
66666
99999999
66656565
22222
2
输出样例2:
6
4
9
4
1
1
参考:poj1019
这弔题卡了我一天,一看是poj的,那没事了。福大对大一的真狠啊。
#include<bits/stdc++.h>
using namespace std;
unsigned a[40000];//第i天 增加 的硬币的长度
unsigned b[40000];//1到i天所有硬币的长度
void f(){
a[1]=b[1]=1;
for(int i=2;i<40000;i++){
a[i]=a[i-1]+(int)log10(i)+1;//log10(i)+1 例:122,(int)lg122=2,+1,3位数
b[i]=b[i-1]+a[i];
}
}
void cal(int n){
int i=1;
while(b[i]<n) i++;
n-=b[--i];//n在第i组,n置为在i组中的位置
int len=0;//第i组长度
for(i=1;len<n;i++){
len+=(1+(int)log10(i));
}
cout<<(i-1)/(int)pow(10,len-n)%10<<endl;
//i=i-1可能不是一个1位数,此时i可能是123,12,1234等等,n才是指向答案的
//pow用来把n后面的无效位消去,例如123,n指向2,len-n就是剩下的位数
//(i-1)/(int)pow(10,len-n)消掉无效位,此时最后一位就是答案
}
int main(){
int n;cin>>n;
f();//别忘
while(n--){
int a;cin>>a;
cal(a);
}
return 0;
}