当前位置:编程学习 > C/C++ >>

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++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,