首页 > 代码库 > 北大ACM(POJ1019-Number Sequence)

北大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]的最大数j36         num -= table[j-1];//num在[1...j]中的偏移量37         for(k=1;num>b[k];k++);//num所在数字有几位:如 num偏移为12,所在数字为11,长度k=238         //下面的两个公式简单说明一下:39         //如 j=101:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 100 10140         //当所在数字(同上面注释里的所在数字)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 }

 

北大ACM(POJ1019-Number Sequence)