轉載請註明出處:優YoU http://user.qzone.qq.com/289065406/blog/1301527312ios
大體題意:函數
有一串數字串,其規律爲spa
1 12 123 1234 12345 123456 1234567 12345678 123456789 12345678910 1234567891011 123456789101112······kcode
輸入位置n,計算這一串數字第n位是什麼數字,注意是數字,不是數!例如12345678910的第10位是1,而不是10,第11位是0,也不是10。總之多位的數在序列中要被拆分爲幾位數字,一個數字對應一位。blog
解題思路:ci
首先建議數學底子很差的同窗,暫時放一放這題,太過技巧性了,連理解都很困難get
模擬分組,把1看作第1組,12看作第2組,123看作第3組……那麼第i組就是存放數字序列爲 [1,i]的正整數,但第i組的長度不必定是i原型
已知輸入查找第n個位的n的範圍爲(1 ≤ n ≤ 2147483647),那麼至少要有31268個組才能使得數字序列達到有第2147483647位數學
注意:2147483647恰好是int的正整數最大極限值( ),因此對於n用int定義就足矣。可是s[31268]存在超過2147483647的位數,所以要用unsigned 或long 之類的去定義s[]io
詳細的解題思路請參照程序的註釋。
其中數學難點有2:
(int)log10((double)i)+1
(i-1)/(int)pow((double)10,len-pos)%10
很是技巧性的處理手法,其意義已在程序中標明
另外要注意的就是log()和pow()函數的使用
兩個都是重載函數,函數原型分別爲
double log(double)
float log(float)
double pow(double , double)
float pow(float ,float)
因此當傳參的類型不是double或float時,必須強制轉換爲其中一種類型,不然編譯出錯。通常建議用double
//Memory Time 02.//476K 0MS 03. 04.#include<iostream> 05.#include<math.h> 06.using namespace std; 07. 08.const int size=31269; 09. 10.unsigned a[size]; //a[i] 表示第i組數字序列的長度 11.unsigned s[size]; //s[i] 表示前i組數字序列的長度 12. //第i組存放的數字序列爲 [1,i]的正整數,但第i組的長度不必定是i 13. //例如數字13要被看作1和3兩個位,而不是一個總體 14. 15./*打表,預先獲取第2147483647個位的序列分組狀況*/ 16. 17.void play_table(void) 18.{ 19. a[1]=s[1]=1; 20. for(int i=2;i<size;i++) 21. { 22. a[i]=a[i-1]+(int)log10((double)i)+1; //log10(i)+1 表示第i組數字列的長度 比 第i-1組 長的位數 23. s[i]=s[i-1]+a[i]; //前i組的長度s[i] 等於 前i-1組的長度s[i-1] + 第i組的長度a[i] 24. } //log()是重載函數,必須對int的i強制類型轉換,以肯定參數類型 25. return; 26.} 27. 28./*計算序列第n個位置上的數字*/ 29. 30.int compute(int n) 31.{ 32. int i=1; 33. while(s[i]<n) 34. i++; //肯定整個數字序列的第n個位置出如今第i組 35. 36. int pos=n-s[i-1]; //pos爲 整個數字序列的第n個位置 在 第i組中的下標值 37. 38. int len=0; 39. for(i=1;len<pos;i++) //從第1組開始遍歷第i前的每個組,利用log10(i)+1遞推第i組的長度 40. len+=(int)log10((double)i)+1; //len爲第i組(n所在的組)的長度 41. 42. return (i-1)/(int)pow((double)10,len-pos)%10; 43. //之因此i-1,是由於前面尋找第i組長度時,i++多執行了一次 44. //i=i-1 此時i恰好等於第n位個置上的數 (數是總體,例如123一百二十三,i恰好等於123,但n指向的多是1,2或3) 45. //pos爲n指向的數字在第i組中的下標值 46. //len爲第i組的長度 47. //那麼len-pos就是第i組中pos位置後多餘的數字位數 48. //則若要取出pos位上的數字,就要利用(i-1)/pow(10,len-pos)先刪除pos後多餘的數字 49. //再對剩下的數字取模,就能夠獲得pos 50. //例如要取出1234的2,那麼多餘的位數有2位:34。那麼用1234 / 10^2,獲得12,再對12取模10,就獲得2 51. 52.} //pow()是重載函數,必須對int的i強制類型轉換,以肯定參數類型 53. 54.int main(void) 55.{ 56. play_table(); 57. 58. int test; 59. cin>>test; 60. while(test--) 61. { 62. int n; 63. cin>>n; 64. cout<<compute(n)<<endl; 65. } 66. return 0; 67.}