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 }