poj1019 递推关系

来源:互联网 发布:matlab编程作业答案 编辑:程序博客网 时间:2024/04/27 20:14

给定一个序列有如下特征:
1.S1S2…Sk
2.每一组子序列Sk为:1,2,……,k
例如:11212312341234512345612345671234567812345678912345678910123456789101112345678910 (长度为80)
现给定一个数n,输出上述序列第n个“字符”是多少。
AC/216K/0MS

#include<iostream>using namespace std;int c[10];  //存放n的十进制,c[0]记录长度long long b[35000],a[6];int m[6]={1,10,100,1000,10000,100000};  //m[i]表示i+1位数字中最小的数/*计算所有小于等于n并且和n具有相同位数的数组成的序列的总长度*/int work(int n){    c[0]=0;    while(n)    {        c[++c[0]]=n%10;        n/=10;    }    int sum=0;    for(int i=c[0];i>0;i--)    {        int t=c[i];        if(i==c[0]) t--;        sum+=t*m[i-1];    }    return (sum+1)*c[0];}/*打表计算序列S1S2...Sk的长度并存入b[k]中*/void play_table(){    int i,k=1;    /*a[i]记录所有长度小于等于i的数组成的序列的总长度*/    a[0]=0;    for(i=1;i<6;i++)    {        a[i]=(k*10-k)*i;        a[i]+=a[i-1];        k*=10;    }    b[0]=0;    for(i=1;i;i++)    {        b[i]=work(i);        b[i]+=a[c[0]-1];        b[i]+=b[i-1];        if(b[i]>2147483647) break;    }}/*计算m的第n位数字*/int caclu(int m,int n){    c[0]=0;    while(m)    {        c[++c[0]]=m%10;        m/=10;    }    return c[c[0]-n+1];}/*计算第n个数字*/int solve(int n){    int i;    for(i=0;i>=0;i++)        if(b[i]<n&&b[i+1]>=n)   break;         //满足条件时跳出,位于子序列S(i+1)中    n-=b[i];    for(i=0;i>=0;i++)        if(a[i]<n&&a[i+1]>=n)    break;    n-=a[i]; i++;    int ans=m[i-1]+(n-1)/i; //第n个数字是ans的第n-((n-1)/i)*i位数    return caclu(ans,n-((n-1)/i)*i);}int main(){    play_table();    int t,n;    cin>>t;    while(t--)    {        cin>>n;        cout<<solve(n)<<endl;    }    return 0;}
1 0
原创粉丝点击