poj1019組合數學

題意:給定一個序列,問序列第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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章