poj 1019 Number Squence
2013-11-15 21:44
246 查看
题目大意:
给定N组数字串,每个数字串都是从1,2······按升序排列的正整数,例如:1 12 123 1234 12345 123456·····,问第n位所指的数字是几?例如:1 12 123 1234 12345······ 第3位是2,第六位是3,第8位是2。
分析:
如果是1--9的数字,每一个数占一位,10--99每个数字占2位,100--999每个数字占三位等等,所以在序列中要求第几位是什么,有点困难。
1)定义两个数组arr[i],sum[i],arr1[i]表示的是第i组有多少位(也即是[1,i],有上面可知,其长度不一定为i),sum[i]表示的是第i组及其以前各组位数之和;由于要查询的位数n的最大值为2147483647,所以要注意数据!仔细分析可知,至少需要31268个数组才可以使得存放的数字序列达到2147483647,不过sum[]却是不行的,因此他要定义为long
或者unsigned2147483647,而n可以用int表示.其中arr[],sum[]的推算:arr[i]=arr[i-1]+(int)log10((double)i)+1;sum[i]=sum[i-1]+arr[i];另外我们可以再打表出这2147483647位的情况:
2)找出第n位在哪个数组里,
此时我们可以知道包含第n位的数组是arr[i],然后用一个变量pos代替n指向的数字;pos = n - s[i-1];
3)在a[i]中找出,当加入数字i时恰好包含第n位时的长度(即位数)len,
此时可以知道,当加入i-1时较好包含第n位,len也求得。
4)k = (i - 1)/pow(10,len-pos)表示pos(或者n)之后的数字全部被截去,然后k%10即为所求,好好揣摩这一块。
给定N组数字串,每个数字串都是从1,2······按升序排列的正整数,例如:1 12 123 1234 12345 123456·····,问第n位所指的数字是几?例如:1 12 123 1234 12345······ 第3位是2,第六位是3,第8位是2。
分析:
如果是1--9的数字,每一个数占一位,10--99每个数字占2位,100--999每个数字占三位等等,所以在序列中要求第几位是什么,有点困难。
1)定义两个数组arr[i],sum[i],arr1[i]表示的是第i组有多少位(也即是[1,i],有上面可知,其长度不一定为i),sum[i]表示的是第i组及其以前各组位数之和;由于要查询的位数n的最大值为2147483647,所以要注意数据!仔细分析可知,至少需要31268个数组才可以使得存放的数字序列达到2147483647,不过sum[]却是不行的,因此他要定义为long
或者unsigned2147483647,而n可以用int表示.其中arr[],sum[]的推算:arr[i]=arr[i-1]+(int)log10((double)i)+1;sum[i]=sum[i-1]+arr[i];另外我们可以再打表出这2147483647位的情况:
void Print_Table( ) { arr[1] = arr[1] = 1; for(int i = 2; i < 31269; i++) { arr[i] = arr[i-1] + (int)log10((double)i)+1; sum[i] = sum[i-1] + arr[i]; } return; }
2)找出第n位在哪个数组里,
int i = 1; while(sum[i] < n) i++;
此时我们可以知道包含第n位的数组是arr[i],然后用一个变量pos代替n指向的数字;pos = n - s[i-1];
3)在a[i]中找出,当加入数字i时恰好包含第n位时的长度(即位数)len,
int len = 0; for(i = 1; len < pos; i++) len += (int)log10((double)i)+1;
此时可以知道,当加入i-1时较好包含第n位,len也求得。
4)k = (i - 1)/pow(10,len-pos)表示pos(或者n)之后的数字全部被截去,然后k%10即为所求,好好揣摩这一块。
#include<iostream> #include<math.h> using namespace std; const int MAXN=31269; long long arr[MAXN]; long long sum[MAXN]; void Print_Table() { arr[1] = sum[1] = 1; for(int i = 2; i < MAXN; i++) { arr[i] = arr[i-1] + (int)log10((double)i)+1; //log10(i)+1 表示第i组数字列的长度 比 第i-1组 长的位数 sum[i] = sum[i-1] + arr[i]; //前i组的长度s[i] 等于 前i-1组的长度s[i-1] + 第i组的长度a[i] } //log()是重载函数,必须对int的i强制类型转换,以确定参数类型 return; } int compute(int n) { int i = 1; while(sum[i] < n) i++; int pos = n - sum[i-1]; int len = 0; for(i=1; len < pos; i++) len += (int)log10((double)i)+1; return (i-1)/(int)pow((double)10,len-pos)%10; } int main() { Print_Table(); int T; cin>>T; while(T--) { int n; cin>>n; cout<<compute(n)<<endl; } return 0; }
相关文章推荐
- POJ 1019 Number Sequence
- poj 1019
- POJ 1019 Number Sequence 难
- poj 1019 Number Sequence
- poj解题报告——1019
- Poj 2593 动态规划 Max Squence
- POJ 1019 Number Sequence
- POJ 1019 数学题
- poj 1019 Number Sequence
- poj 1019 Number Sequence
- POJ1019:Number Sequence
- POJ 1019
- poj 1019
- poj 1019 Number Sequence 对数的分解应用
- 第十七天:poj1019(纯属数学题目,找到规律就能解出)
- POJ 1019 解题报告
- poj1019 Number Sequence 思维 递推
- poj 1019 Number Sequence
- poj 1019 Number Sequence
- poj 1019 Number Sequence(打表+二分)