poj1019组合数学

来源:互联网 发布:mac 10.12.6 编辑:程序博客网 时间:2024/06/06 06:29

题意:给定一个序列,问序列第i位数字;
思路:显而易见,在1~9中,序列长度依次增加1,在10~99中,序列长度依次增加2。那么我们可以求出所有num[n](num[n]以数n结尾的序列长度),因为给的条件(1 ≤ i ≤ 2147483647),所以n最大为31269(对所有的num[n]求个和就知道了);具体思路看代码吧;

#include<iostream>#include<algorithm>#include<string>#include<cstring>#include<map>#include<queue>#include<cmath>#include<stack>#include<vector>#include<cstdio>#define MAXN 33000#define INF 0x3f3f3f3f#define lmid l,m,rt<<1#define rmid m+1,r,rt<<1|1#define ls rt<<1#define rs rt<<1|1#define Mod 1000000007#define i64 __int64#define LIMIT_ULL 100000000000000000#define Max(a,b) (a>b)?a:b#define lowbit(x) x&(-x)using namespace std;typedef long long ll;int s[31269];char ch[10];void init(){     s[0]=0;     for(int i=1;i<=31268;i++)     {          int j=i;          int t=0;          while(j)          {               j/=10;               t++;          }          s[i]=s[i-1]+t;     }}int main(){     init();     int t;     scanf("%d",&t);     while(t--)     {          int n;          scanf("%d",&n);          int m;          for(int i=1;i<=31268;i++)//知道n所在的序列,该序列以m结尾          {               if(n<s[i])               {                    m=i;                    break;               }               n-=s[i];          }          if(n==0)//n==0说明n为前一个序列的末尾,即(m-1)%10          {               cout<<(m-1)%10<<endl;               continue;          }          for(int i=m-1;i>=1;i--)//找到第一个长度小于n的序列,该序列以m结尾          {               if(s[i]<=n)               {                    m=i;                    n-=s[i];                    break;               }          }          if(n==0)//n==0说明n为该序列的末尾,即m%10          {               cout<<m%10<<endl;               continue;          }          for(int i=m+1;;i++)//枚举,确定n所在位置          {               int j=i;               int t=0;               while(j)               {                    j/=10;                    t++;               }               if(n>=t)               {                    n-=t;                    if(n==0)                    {                         cout<<i%10<<endl;                         break;                    }                    continue;               }               if(n<t)               {                    sprintf(ch,"%d",i);                    cout<<ch[n-1]<<endl;                    break;               }          }     }     return 0;}