zoj 1410 Number Sequence

来源:互联网 发布:罗技宏编程下载 编辑:程序博客网 时间:2024/05/18 00:23

部分等差数列。个位数时等差为1,共有9个,2位数时等差为2,共有90个,三位时等差为3,共有900个,以此类推。。。。。

将每增加一个数时,数字串总长度存起来,二分查找到某一个值,下面暴力。。。

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define ls rt<<1
#define rs ls1
#define lson l,mid,ls
#define rson mid+1,r,rs
#define middle (l+r)>>1
#define eps (1e-9)
#define type int
#define clr_all(x,c) memset(x,c,sizeof(x))
#define clr(x,c,n) memset(x,c,sizeof(x[0])*(n+1))
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define M 32000
ll n,len[M],sum[M];
void Init(){
int i=1,t=9,j;
ll p=1;
len[0]=0,sum[0]=0;
while(i<M){
for(j=1;j<=t;j++)
if(i<M){
len[i]=len[i-1]+p;
sum[i]=len[i]+sum[i-1];
i++;
}else break;
p+=1;
t*=10;
}
}
int bSearch(int l,int r){
if(r-l==1)
return l;
int mid=(l+r)/2;
if(sum[mid]<n)
return bSearch(mid,r);
else 
return bSearch(l,mid);
}
int getDN(int x){
int cnt=0;
while(x>0)x/=10,cnt++;
return cnt;
}
int main(){
    int T,i,j,dig; ll m,num,x,p,k;
    Init();
    scanf("%d",&T);
while(T--){
scanf("%lld",&n);
if(n==1)printf("1\n");
else {
i=bSearch(1,M-1);
m=n-sum[i];
num=0;
for(j=1;j<M;j++){
x=getDN(j);
num+=x;
if(num>=m){
p=num-m;
for(k=0;k<p;k++)j/=10;
dig=j%10;
break;
}
}
printf("%d\n",dig);
}

    return 0;
}

原创粉丝点击