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 }