首页 > 代码库 > poj 1019 Number Sequence (数学)

poj 1019 Number Sequence (数学)

链接:http://poj.org/problem?id=1019

分析:就是计数的问题。。可以先算出112123...m共有多少位,具体式子看代码。。然后二分取一个最大的小于n的m,接下来考虑123...m有多少位,再二分一下求解就可以了。。具体式子还是看代码。。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll;
 6 ll q[10],powten[11];
 7 long long p[100005];
 8 void CalQ(){
 9     powten[0]=1;
10     for(int i=1;i<=10;i++)powten[i]=powten[i-1]*10;
11     q[0]=0;
12     for(int i=1;i<=9;i++)
13         q[i]=q[i-1]+9*i*powten[i-1];
14 }
15 ll f(int x){
16     if(x==0)return 0;
17     int len=0,x0=x;
18     while(x0){
19         len++;x0/=10;
20     }
21     if(len==1)return x;
22     return q[len-1]+(ll)len*(x-powten[len-1]+1);
23 }
24 void CalP(){
25     CalQ();
26     p[0]=0;
27     p[1]=1;
28     for(int i=2;i<100005;i++){
29         p[i]=p[i-1]+f(i);
30 //        if(i%500==0){
31 //            i=i;
32 //            memset(p,0,i*sizeof(int));
33 //        }
34     }
35 }
36 int dich(int n){
37     int l=0,r=4e4,m=(l+r)/2;
38     while(l<=r&&l!=m){
39         ll t=p[m];
40         if(t==n)return m-1;
41         else if(t>n)r=m;
42         else l=m;
43         m=(l+r)/2;
44     }
45     return r-1;
46 }
47 int Dich(int n){
48     int l=0,r=n,m=(l+r)/2;
49     while(l<=r&&l!=m){
50         int t=f(m);
51         if(t==n)return m;
52         else if(t>n)r=m;
53         else l=m;
54         m=(l+r)/2;
55     }
56     return r-1;
57 }
58 int solve(int n){
59     int m=dich(n);
60     int h=Dich(n-p[m]);
61     int k=n-f(h)-p[m]-1;
62     if(k==-1)return h%10;
63     char str[15];
64     sprintf(str,"%d",h+1);
65     return str[k]-0;
66 }
67 char s[1000000];
68 //void Gets(){
69 //    s[0]=‘\0‘;
70 //    char str[5];
71 //    for(int i=1;i<500;i++){
72 //        for(int j=1;j<=i;j++){
73 //            sprintf(str,"%d",j);
74 //            strcat(s,str);
75 //        }
76 //    }
77 //}
78 //int test(int n){
79 //    return s[n-1]-‘0‘;
80 //}
81 int main(){
82     CalP();
83     //Gets();
84     //freopen("e:\\out.txt","w",stdout);
85     //freopen("e:\\in.txt","r",stdin);
86     int t,n;
87     scanf("%d",&t);
88     n=1;
89     while(t--){
90         scanf("%d",&n);
91         //int a=test(n),b=solve(n);
92         //printf("%d ",a);
93         printf("%d\n",solve(n));
94         //if(a!=b)cout<<n<<"***************\n"<<endl;
95     }
96     return 0;
97 }

 

poj 1019 Number Sequence (数学)