POJ1019:Number Sequence(组合计数)
Number Sequence
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 28810 Accepted: 8003
Description
A single positive integer i is given. Write a program to find the digit located in the position i in the sequence of number groups S1S2...Sk. Each group Sk consists of a sequence of positive integer numbers ranging from 1 to k, written one after another. www.zzzyk.com
For example, the first 80 digits of the sequence are as follows:
11212312341234512345612345671234567812345678912345678910123456789101112345678910
Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10), the number of test cases, followed by one line for each test case. The line for a test case contains the single integer i (1 ≤ i ≤ 2147483647)
Output
There should be one output line per test case containing the digit located in the position i.
Sample Input
2
8
3
Sample Output
2
2
Source
Tehran 2002, First Iran Nationwide Internet Programming Contest
MYCode:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
#define MAX 40010
LL sum[MAX];
LL len[MAX];
int func(int x)
{
int ct=0;
while(x>=1)
{
ct++;
x/=10;
}
return ct;
}
void cal()
{
int x;
for(x=1;x<=9;x++)
len[x]=x;
int i;
for(x=10;x<=40000;x++)
{
int d=func(x);
int tot=0;
for(i=1;i<d;i++)
{
int num=(int)(pow(10.0,i)-pow(10.0,i-1));
tot+=i*num;
}
int add=x-(int)pow(10.0,d-1)+1;
tot+=add*d;
len[x]=tot;
}
sum[0]=0;
for(i=1;i<=40000;i++)
{
sum[i]=sum[i-1]+len[i];
}
}
int b_search(int k)
{
int lt=1,rt=40000;
while(lt<rt)
{
int mid=(lt+rt)/2;
if(sum[mid]<k)
lt=mid+1;
else
rt=mid;
}
return rt;
}
int find(int r,int x)
{
int lt=1,rt=x;
while(lt<rt)
{
int mid=(lt+rt)/2;
if(len[mid]<r)
lt=mid+1;
else
rt=mid;
}
int add=r-len[rt-1];
int st[20];
int ct=0;
while(rt>=1)
{
st[ct++]=rt%10;
rt/=10;
}
return st[ct-add];
}
int solve(int k)
{
int x=b_search(k);
int r=k-sum[x-1];
return find(r,x);
}
int main()
{
int k;
cal();
int i;
int t;
//cout<<sum[40000]<<endl;
scanf("%d",&t);
while(t--)
{
scanf("%d",&k);
int ans=solve(k);
printf("%d\n",ans);
}
}
//16MS
len[i]:表示以从1开始,以i结尾的序列的长度
sum[i]:表示以1,2,3,...,i结尾的序列的长度之和
经检查,sum[40000]已经覆盖题目的数据范围.
补充:软件开发 , C++ ,