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;
}