把一位数、两位数、三位数……这些所在的范围分开判断
可得1~9这些数范围在[1,9]内
10~99内共有90个数,每个数占两位,所以共有180位在,范围在[10,189]内
同理,100~999内共有900个数,每个数占三位,所以共有2700位在,范围在[190,2889]内
……
最后对于范围,可以得出一个规律
9 189 2889 38889 488889 ......
知道了范围,就可以求指定的答案了
比如输入一个数n范围在[190,2889]内
就能知道这是个三位数
n-190后,0/1/2对应数字100的三位,3/4/5对应数字101的三位,以此类推
所以(n-190)/3+100可以找出对应的数字
而(n-190)%3可以找出是对应的数字的第几位
(代码中写成(n-189+2)/3+99,意思相同,2代表位数减1)
因此对于Ⅰ题,可以直接暴力敲代码
#include<bits/stdc++.h> using namespace std; int main(){ int q,n,d,dd; cin>>q; while(q--){ cin>>n; if(n<=9) cout<<n<<endl; else if(n>9&&n<=189){ d=(n-9+1)/2+9; if(n&1) cout<<d%10<<endl; else cout<<d/10<<endl; } else if(n>189&&n<=2889){ d=(n-189+2)/3+99; dd=(n-189)%3; if(dd==0) cout<<d%10<<endl; else if(dd==1) cout<<d/100<<endl; else cout<<d/10%10<<endl; } else{ d=(n-2889+3)/4+999; dd=(n-2889)%4; if(dd==0) cout<<d%10<<endl; else if(dd==1) cout<<d/1000<<endl; else if(dd==2) cout<<d/100%10<<endl; else cout<<d/10%10<<endl; } } return 0; }
对于Ⅱ,这种方法显然也可行
#include<bits/stdc++.h> using namespace std; int main(){ int q,n,d,dd; cin>>q; while(q--){ cin>>n; if(n<=9) cout<<n<<endl; else if(n>9&&n<=189){ d=(n-9+1)/2+9; if(n&1) cout<<d%10<<endl; else cout<<d/10<<endl; } else if(n>189&&n<=2889){ d=(n-189+2)/3+99; dd=(n-189)%3; if(dd==0) cout<<d%10<<endl; else if(dd==1) cout<<d/100<<endl; else cout<<d/10%10<<endl; } else if(n>2889&&n<=38889){ d=(n-2889+3)/4+999; dd=(n-2889)%4; if(dd==0) cout<<d%10<<endl; else if(dd==1) cout<<d/1000<<endl; else if(dd==2) cout<<d/100%10<<endl; else cout<<d/10%10<<endl; } else{ d=(n-38889+4)/5+9999; dd=(n-38889)%5; if(dd==0) cout<<d%10<<endl; else if(dd==1) cout<<d/10000<<endl; else if(dd==2) cout<<d/1000%10<<endl; else if(dd==3) cout<<d/100%10<<endl; else cout<<d/10%10<<endl; } } return 0; }
但是对于Ⅲ,1e18的范围就只能循环找规律了
数据打个表用循环做!
以下代码三道题目均能使用
#include<stdio.h> int main(){ long long q,n,d,dd,i,j,qq[16]={9LL,189LL,2889LL,38889LL,488889LL,5888889LL,68888889LL,788888889LL,8888888889LL,98888888889LL,1088888888889LL,11888888888889LL,128888888888889LL,1388888888888889LL,14888888888888889LL,158888888888888889LL},qd[17]={9LL,99LL,999LL,9999LL,99999LL,999999LL,9999999LL,99999999LL,999999999LL,9999999999LL,99999999999LL,999999999999LL,9999999999999LL,99999999999999LL,999999999999999LL,9999999999999999LL},ed[18]={1LL,10LL,100LL,1000LL,10000LL,100000LL,1000000LL,10000000LL,100000000LL,1000000000LL,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL}; scanf("%lld",&q); while(q--){ scanf("%lld",&n); if(n<=9) printf("%lld ",n); else{ for(i=0;i<=15;i++){ if(i<15&&n>qq[i]&&n<=qq[i+1]||i==15&&n>qq[15]){ d=(n-qq[i]+i+1)/(i+2)+qd[i]; dd=(n-qq[i])%(i+2); if(dd==0) printf("%lld ",d%10); for(j=1;j<i+2;j++){ if(dd==j){ printf("%lld ",d/ed[i+2-j]%10); break; } } break; } } } } return 0; }
完美!(