HDOJ 1060 / HDOJ 1061/ HDOJ 1568 总结(如何求大数最左边最右边的数)

      HDOJ 1060 / HDOJ 1568 这种题目就是再说一个问题:如何求一个大数num的最左边的一个或几个数字?

     其实这两题的解法都是一样的,给定一个num(当num大到无法用int或long long储存时可以直接用lg num储存它),num = 10 ^ n * a. n为num的位数-1 , a为小于10的一个实数..   比如27 = 10 ^ 1 * 2.7   所以目标就是求出a,再对a取整就是num最左边的数字.

    1.因为  lg num = lg (10 ^ n) + lg a = d = n + x   (a<10,x< 1)    其中:  a = 10 ^ x ; n= int (lg num)=lg num - x ;

    2.所以 a=10^(lg num-n);

    3.对a取整就是num最左边的数字了.....

    下面开始贴代码:

     HDOJ 1060:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        double num=0;
        int N;
        cin>>N;
        num=1.0*N*log10(N*1.0);        //logN^N
        double x=num-(__int64)num;
        int a=pow(10.0,x);
        cout<<a<<endl;
    }
    return 0;
}

HDOJ 1568:

这题要先知道斐波那契数列存在通项公式:

F(n)=(1/√5)*{[(1+√5)/2]^n - [(1-√5)/2]^n}

代码如下:

#include<iostream>
#include<cmath>
using namespace std;
int main()
{ 
    int fib[21],i,n;
    fib[0]=0;fib[1]=1;
    for(i=2;i<21;i++)
    fib[i]=fib[i-1]+fib[i-2];
    while(scanf("%d",&n)!=EOF)
    {
        if(n<=20)
        printf("%d\n",fib[n]);
        else
        {
            double p=n*log10((1+sqrt(5.0))*0.5)-log10(sqrt(5.0));
            p=p-int(p);
            int res=pow(10.0,p)*1000;
            printf("%d\n",res);
        }
    }
    return 0;
}

附赠1061:Rightmost Digit;

 这种题

 1.暴力

 2.打表

 3.找规律,找循环节:

贴下代码:

#include <stdio.h>
int main()
{
     int num,result;
     __int64 value;
     scanf("%d",&num);
     while(num--)
     {
         scanf("%I64d",&value);
         int v=value%10;
         int circle=value%4;
         circle==0?circle=4:1;
         result=1;
         while(circle--)
             result*=v;
         printf("%d\n",result%10);
     }
     return 0;
}



   
  


你可能感兴趣的:(HDOJ 1060 / HDOJ 1061/ HDOJ 1568 总结(如何求大数最左边最右边的数))