poj1019

http://poj.org/problem?id=1019web

大體題意:ide

有一串數字串,其規律爲spa

1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 123456789101112······k3d

輸入位置n,計算這一串數字第n位是什麼數字,注意是數字,不是數!例如12345678910的第10位是1,而不是10,第11位是0,也不是10。總之多位的數在序列中要被拆分爲幾位數字,一個數字對應一位。code

 

解題思路:orm

 

模擬分組,把1看作第1組,12看作第2組,123看作第3組……那麼第i組就是存放數字序列爲 [1,i]的正整數,但第i組的長度不必定是iblog

已知輸入查找第n個位的n的範圍爲(1 ≤ n ≤ 2147483647),那麼至少要有31268個組才能使得數字序列達到有第2147483647位ci

注意:2147483647恰好是int的正整數最大極限值( ),因此對於n用int定義就足矣。可是s[31268]存在超過2147483647的位數,所以要用unsigned 或long 之類的去定義s[]get

 1 #include<stdio.h>
 2 #include<math.h>
 3 #define N 32000
 4 unsigned  a[N];//第i組數字序列的長度
 5 unsigned s[N];//前i組數字序列的長度
 6 int main()
 7 {
 8     int i;
 9     a[1]=s[1]=1;
10     for(i=2;i<N;i++)
11     {
12         a[i]=a[i-1]+(int)log10((double)i)+1;//(int)log10(double)i表示第i組的序列比第i-1組長的位數
13         s[i]=s[i-1]+a[i];
14     }
15     int n,m,j,len,k;
16     scanf("%d",&m);
17     while(m--)
18     {
19         scanf("%d",&n);
20         j=1;
21         while(s[j]<n)
22             j++;   //肯定第n個位置在第幾組
23         k=n-s[j-1];// 第n個位置 在 第j組中的下標值
24         len=0;
25         for(i=1;len<k;i++)
26             len+=(int)log10((double)i)+1;
27         int num=(i-1)/(int)pow((double)10,len-k)%10; //之因此i-1,是由於前面尋找第i組長度時,i++多執行了一次
28                                                       //i=i-1 此時i恰好等於第n位個置上的數 (數是總體,例如123一百二十三,i恰好等於123,但n指向的多是1,2或3)
29                                                      //pos爲n指向的數字在第i組中的下標值
30                                                      //len爲第i組的長度
31                                                     //那麼len-pos就是第i組中pos位置後多餘的數字位數
32                                                     //則若要取出pos位上的數字,就要利用(i-1)/pow(10,len-pos)先刪除pos後多餘的數字
33                                                     //再對剩下的數字取模,就能夠獲得pos
34                                                     //例如要取出1234的2,那麼多餘的位數有2位:34。那麼用1234 / 10^2,獲得12,再對12取模10,就獲得2
35         printf("%d\n",num);
36     }
37     return 0;
38 }
View Code
相關文章
相關標籤/搜索