poj 1019 Number Sequence

来源:互联网 发布:电脑测ping软件 编辑:程序博客网 时间:2024/05/09 05:16

题目大意:       

         

        一些数字按照112123123412345.......的顺序排列下去的,然后输入一个不大于2147483647(2^31-1 (^表示2的多少次方) )的数,让你就在这个位数上的数字是几。

       注意这里求出来的数字只能是0到9中的,不能是其他的数。

       方法:找到求出每个数的规律,就会发现一位数有9个,两位数90*2个,三位数900*3个,先确定它是几位数,在逐个求出。

       


poj 1019  Number Sequence:

#include<stdio.h>#include<math.h>void GetDigit(int pos){    if(pos<=9) printf("%d\n",pos);    else if(pos<=189)    {        if((pos-9)%2==0) printf("%d\n",((pos-9)/2-1)%10);        else printf("%d\n",(pos-9)/20+1);    }    else if(pos<=2889)    {        if((pos-189)%3==0) printf("%d\n",((pos-189)/3-1)%10);        else if((pos-189)%3==2) printf("%d\n",((pos-189)/30)%10);        else printf("%d\n",(pos-189)/300+1);    }    else if(pos<=38889)    {        if((pos-2889)%4==0) printf("%d\n",((pos-2889)/4-1)%10);        else if((pos-2889)%4==3) printf("%d\n",((pos-2889)/40)%10);        else if((pos-2889)%4==2) printf("%d\n",((pos-2889)/400)%10);        else printf("%d\n",(pos-2889)/4000+1);    }    else    {        if((pos-38889)%5==0) printf("%d\n",((pos-38889)/5-1)%10);        else if((pos-38889)%5==4) printf("%d\n",((pos-38889)/50)%10);        else if((pos-38889)%5==3) printf("%d\n",((pos-38889)/500)%10);        else if((pos-38889)%5==2) printf("%d\n",((pos-38889)/5000)%10);        else printf("%d\n",(pos-38889)/50000+1);    }}int main(){    double tmp=6050195089.0;    int t;    int num;    int row;    int m;    int pos;    while(scanf("%d",&t)!=EOF)    {        while(t--)        {            scanf("%d",&num);            if(num<=45)//表示只有一位数的时候,最多能组成45位数            {//1+2....+9                m=num;                //求方程n(n+1)/2=m的通解,n(n+1)/2是数列的求和公式                row=(int)((sqrt(8.0*m+1)-1)/2);                //确定pos的位置,因为row是由double型转化为整型,因此求出来的                //row的值小于等于方程的解                pos=m-row*(row+1)/2;                if(pos==0) printf("%d\n",row);                else printf("%d\n",pos);            }            else if(num<=9045)//表示有一位数和两位数,最多能组成9045位数            {//1+2+...+9+11+13+.....180  45+9*90+(2+180)*90/2=9045                m=num-45;                //求方程(11+11+(n-1)*2)*n/2的通解,(9+(n-1)*2)*n/2是数列的求和公式                row=(int)(sqrt(m+25.0)-5);                pos=m-row*row-10*row;//确定pos的位置                if(pos==0)printf("%d\n",(row+9)%10);                else GetDigit(pos);            }            else if(num<=1395495)//表示有一位数、两位数和三位数,最多能组成1395495位数            {//9045+189*900+(3+2700)*900/2=1395495                m=num-9045;                row=(int)((sqrt(145161+24.0*m)-381)/6);//求方程(192+192+(n-1)*3)*n/2的通解                pos=m-(3*row*row+381*row)/2;                if(pos==0) printf("%d\n",(row+99)%10);                else GetDigit(pos);            }            else if(num<=189414495)//表示有一位数、两位数、三位数和四位数,最多能组成189414495            {//1395495+2889*9000+(4+36000)*9000/2=189414495                m=num-1395495;                //求方程(2889+4+2889+4+(n-1)*4)*n/2的通解                row=(int)((sqrt(8.0*m+8357881)-2891)/4);                pos=m-2*row*row-2891*row;                if(pos==0) printf("%d\n",(row+999)%10);                else GetDigit(pos);            }            else//表示有一位数、两位数、三位数、四位数,和五位数最多能组成的位数            {                m=num-189414495;                //求方程(38889+5+38889+5+(n-1)*5)*n/2的通解                row=(int)((sqrt((double)(tmp +40.0*m))-77783)/10);                pos=m-2.5*row*row-38891.5*row;                if(pos==0) printf("%d\n",(row+9999)%10);                else GetDigit(pos);            }        }    }    return 0;}

0 0
原创粉丝点击