北大ACM(POJ1019-Number Sequence)

Question:http://poj.org/problem?id=1019
问题点:打表。
 1 Memory: 392K        Time: 16MS
 2 Language: C++        Result: Accepted
 3 
 4 #include <iostream>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 #define uint unsigned int
 9 uint table[31269];
10 uint a[6] = {0,1,11,111,1111,11111};//(1-10^k)/(1-10)的对应结果
11 uint b[6] = {0,9,189,2889,38889,488889};//[1...j]中位数变动边界值。如9 10,从个位到十位时记录9的偏移量
12 int getLen(int n)
13 {
14     if(n<10) return 1;
15     else if(n<100) return 2;
16     else if(n<1000) return 3;
17     else if(n<10000) return 4;
18     else return 5;
19 }
20 int main()
21 {
22     uint i=1,seg;
23     memset(table,0,sizeof(table));
24     for(i = 1,seg = 0;i<31269;i++)//打表
25     {
26         seg += getLen(i);
27         table[i] = table[i-1] + seg;
28     }
29     uint eg,num,j,k,bit;
30     cin>>eg;
31     while(eg--)
32     {
33         cin>>num;
34         //if(num==0) break;
35         for(j=1;j<i&&num>table[j];j++);//对应段[1...j]的最大数j
36         num -= table[j-1];//num在[1...j]中的偏移量
37         for(k=1;num>b[k];k++);//num所在数字有几位:如 num偏移为12,所在数字为11,长度k=2
38         //下面的两个公式简单说明一下:
39         //如 j=101:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 100 101
40         //当所在数字(同上面注释里的所在数字)n=19时,偏移量 offset = 19 + (19-9) ,即个位数字数 + 十位数字数
41         //所以,当n的长度为k时,offset = n + (n-9) +(n-99) +...+(n-(k-1个9)) =k(n+1) -(1+10+100+...+10^(k-1))=k(n+1)-(1-10^k)/(1-10)
42         //(1-10^k)/(1-10)已存到数组a中,则offset = k(n+1) - a[k],下面两个公式都是依此推导
43         bit = (num + a[k] - k - 1)%k;//计算num在 所在数字的位置 :如num为13指向所在数字12的十位,则bit=0(bit从数字高位到低位递增)
44         num = (ceil(double(num + a[k])/k-1));//计算num的所在数字的值
45         char buf[10];
46         sprintf_s(buf,"%d",num);
47         cout<<buf[bit]<<endl;//数字转字符串,输出指定位置字符
48     }
49     //system("pause");
50     return 0;
51 }

 

posted @ 2017-03-07 12:12  月生丶  阅读(550)  评论(0编辑  收藏  举报