poj1019_Number_Sequence

  这题目关键是打表,haha[k]数组表示的是S1S2..Sk该串结尾所在的位置。然后用n去找n所在的k值,此时haha[k-1]<n<=haha[k]。然后再算出从haha[k]位置到n一共有多少位,再查出来就行了。

  本来我要用打表+二分的想法,不过后来二分写的不太好一看可以直接遍历就遍历,limit=3万多,直接遍历也行!有时间把这个二分好好的重写一下。

  一点没看题解,做出来挺开心的!

1-9 的长度 = 9

1-99 的长度 = 189

1-999 的长度 =  2889

1-9999的长度 = 38889

31268是事先计算好的,haha[31268]时候正好大于临界值。

poj1019_Number_Sequence
 1 #include <stdio.h>
 2 #define  limit 31268
 3 long long haha[100000];
 4 void init(){
 5     int cnt=1,i;
 6     int t;
 7     haha[0]=0;
 8     for(i=1;i<=65537;++i){
 9         haha[i]=haha[i-1];
10         if(cnt>=10000){
11             haha[i]+=(cnt-10000+1)*5+38889;
12         }
13         else if(cnt>=1000){
14             haha[i]+=(cnt-1000+1)*4+2889;
15         }else if(cnt>=100){
16             haha[i]+=(cnt-100+1)*3+189;
17         }else if(cnt>=10){
18             haha[i]+=(cnt-10+1)*2+9;
19         }else if(cnt>0){
20             haha[i]+=1*cnt;
21         }
22         cnt++;
23         if(haha[i]>2147483647){
24             break;
25         }
26     }
27     return ;
28 }
29 int main(){
30     int t,ii,i,l,r,mid;
31     int n;
32     int pos;
33     int cnt;
34     int tmp;
35     int res;
36     init();
37     while(~scanf("%d",&t)){
38         while(t--){
39             scanf("%d",&n);
40             /*
41             l=0;
42             r=limit;
43             mid=(r+l)/2;
44             while(haha[r]>=n&&n>=haha[l]){
45                 printf("l=%d,r=%d,haha[l]=%lld,haha[r]=%lld\n",l,r,haha[l],haha[r]);
46                 if(n<haha[mid]){
47                     r=mid;
48                 }else if(n>haha[mid])
49                     l=mid;
50                 else break;
51                 mid=(r+l)/2;
52             }
53             pos=mid;
54             */
55             for(i=0;i<=limit;++i){
56                 if(haha[i]>=n)
57                     break;
58             }
59             pos=i;
60             cnt=0;
61             res=-1;
62 //            printf("n=%d,pos=%d,haha[pos]=%lld\n",n,pos,haha[pos]);
63             if(n-(int)haha[pos]<0){
64                 n=(int)haha[pos]-n;
65                 n++;
66                 for(i=pos;i>=1;--i){
67                     int ii=i;
68                     while(ii>0){
69                         tmp=ii%10;
70                         ii=ii/10;
71                         cnt++;
72                         if(cnt==n){
73                             res=tmp;
74                             break;
75                         }
76                     }
77                     if(res!=-1) break;
78                 }
79                 printf("%d\n",res);
80             }else if(n-(int)haha[pos]==0){
81                 printf("%d\n",pos%10);
82             }
83         }
84     }
85     return 0;
86 }
poj1019_Number_Sequence

poj1019_Number_Sequence

上一篇:跟vczh看实例学编译原理——零:序言


下一篇:扁平化设计的美感