您的位置:首页 > 产品设计 > UI/UE

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位的情况:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: