POJ1019-Number Sequence数学

题目链接:http://poj.org/problem?id=1019

题目大意:

  题目的意思很清楚了,就是把数字的每一位都当成是单个的字母来对待,然后求第i位的数是哪一个。(1<=i<=2^31-1)

题目分析:

  仔细观察并通过计算可以得知,想要通过穷举的方式用字符串来处理是行不通的,那就只好乖乖得着规律了。

  按照最大数字为1、2、3……的原则进行分组。发现了如下规律:

  一位数:

  1:1;

  12:2;

  ……

  123456789:9;

  两位数:

  12345678910:11;

  1234567891011:13;

  ……

  12345……99:189;

  最后发现到了五位数的某一位(大于31000,小于32000)时,总长度就已经超过2^31-1了。因而,数据并不算大,可以解决。按照上述规律,定义f[i]为i第一次出现的下标。

  那么就卡出i来,然后计算就可以了!

详细就看代码:

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<string>
  5 using namespace std;
  6 #define MAX 2147483647
  7 long long f[100000];//虽然MAX没有超过int但是所求之数是会超过的
  8 
  9 void init()
 10 {
 11     f[1]=1;
 12     int t=9;
 13     for(int i=2;i<=9;i++)
 14         f[i]=f[i-1]+i;
 15     for(int i=10;i<100;i++)
 16         f[i]=f[i-1]+(t+=2);
 17     for(int i=100;i<1000;i++)
 18         f[i]=f[i-1]+(t+=3);
 19     for(int i=1000;i<10000;i++)
 20         f[i]=f[i-1]+(t+=4);
 21     for(int i=10000;i<32000;i++)//这个上界很是重要!
 22        f[i]=f[i-1]+(t+=5);
 23 }
 24 int main()
 25 {
 26     int t,n;
 27     init();
 28     cin>>t;
 29     while(t--)
 30     {
 31         cin>>n;
 32         if(n==1)
 33         {
 34             cout<<1<<endl;
 35             continue;
 36         }
 37         for(int i=2;i<32000;i++)
 38             if(f[i-1]<n&&f[i]>=n)
 39             {
 40                 int temp=n-f[i-1];//差值
 41                 if(temp>38889)//五位数
 42                 {
 43                     int t=temp-38889;
 44                     int t2=10000+(t-1)/5;
 45                     t-=5*(t2-10000);
 46                     if(t==1)
 47                         cout<<t2/10000<<endl;
 48                     if(t==2)
 49                         cout<<(t2/10/10/10)%10<<endl;
 50                     if(t==3)
 51                         cout<<(t2/10/10)%10<<endl;
 52                     if(t==4)
 53                         cout<<(t2/10)%10<<endl;
 54                     if(t==5)
 55                         cout<<t2%10<<endl;
 56                 }else
 57                 if(temp>2889)//四位数
 58                 {
 59                     int t=temp-2889;
 60                     int t2=1000+(t-1)/4;
 61                     t-=4*(t2-1000);
 62                     if(t==1)
 63                         cout<<t2/1000<<endl;
 64                     if(t==2)
 65                         cout<<(t2/10/10)%10<<endl;
 66                     if(t==3)
 67                         cout<<(t2/10)%10<<endl;
 68                     if(t==4)
 69                         cout<<t2%10<<endl;
 70 
 71                 }else
 72                 if(temp>189)//三位数
 73                 {
 74                     int t=temp-189;
 75                     int t2=100+(t-1)/3;
 76                     t-=3*(t2-100);
 77                     //cout<<"t2="<<t2<<" t="<<t<<endl;
 78                     if(t==1)
 79                         cout<<t2/100<<endl;
 80                     if(t==2)
 81                         cout<<(t2/10)%10<<endl;
 82                     if(t==3)
 83                         cout<<t2%10<<endl;
 84 
 85                 }else
 86                 if(temp>9)//二位数
 87                 {
 88                     int t=temp-9;
 89                     int t2=10+(t-1)/2;
 90                     t-=2*(t2-10);
 91                     if(t==1)
 92                         cout<<t2/10<<endl;
 93                     if(t==2)
 94                         cout<<t2%10<<endl;
 95                 }else
 96                 if(temp>0)//一位数
 97                     cout<<temp<<endl;
 98                 break;
 99             }
100     }
101     return 0;
102 }
POJ1019

  

原文地址:https://www.cnblogs.com/xiaozhuyang/p/POJ1019-NumberSequence.html