hdu acmsteps 2.2

2.2.1 Fibonacci
首先此题的Fibonacci数列太大,n的范围到100,000,000。递归肯定超时。所以去维基百科看了一下,果然有公式。

但是此题只是让输出结果的前四位。对等式两边取log10得到a,然后再求10的a的小数部分次方,得到的值乘以1000既是其的前四位。(仔细想想为什么?)当数列第n项的值小于一万(n<21)直接使用公式就好。
int f1(int n)
{
int ans=(int)( (pow((1+sqrt(5.0))/2,n)-pow((1-sqrt(5.0))/2,n))/sqrt(5.0)+0.5);
return ans;
}
int f2(int n)
{
double a=n*log10( (1+sqrt(5.0))/2)-log10(sqrt(5.0));
return (int)1000*pow(10.0,a-floor(a));
}
2.2.2 Joseph
经典的约瑟夫环问题。其递推公式是:
f[1]=0;
f[i]=(f[i-1]+m)%i; (i>1)
知道了这个,然后搜索一下就行。
具体代码点击这里:http://blog.csdn.net/ouxijv/article/details/6683248
2.2.3 汉诺塔VII
点击这里:http://hi.baidu.com/saintqdd/blog/item/73fae2cf6586bf38f9dc616a.html
我补充一下我的想法:dfs(int *n, int *a,int *b,int *c)
首先,a是源塔,b是辅助塔,c是目标塔。
最大的不可能出现在辅助塔下层,如果出现了就报错,直接返回。
如果最大的出现在源塔,那么说明,下一步要进行的是把源塔上面的n-1个移到辅助塔,而原先的目标塔c作为辅助塔,所以调用dfs(n-1,a,c,b)
如果最大的出现在目标塔,说明下一步要进行的是把辅助塔上n-1个塔移回到目标塔上,源塔a作为辅助塔。
2.2.4 Wolf and Rabbit
一样是判断是否互质。互质的话则一定不存在安全洞。
2.2.5 The 3n + 1 problem
简简单单 爆搜就可以了。
2.2.6 Digital Roots
坑爹。。。。我就说不会那么简单吧。百度一下,才知道原来第一次输入的数字可能很大,得用字符串。我开了20000的字符数组。
2.2.7 Train Problem II
卡特兰数。不过这次用到了一个递归公式。要用数组模拟大整数乘法和除法。注意要先进行乘法,之后再进行除法,否则会因为精度问题出错。
Catalan数的组合公式为 Cn=C(2n,n) / (n+1);
递推公式为 h(n+1 ) = h(n)*(4*n+2) / (n+2);
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int cta[101][200];
bool mul(int *a,int *b,int n)
{
	int i,j,r;
	int d;
	d=2*(2*n+1);
	for(i=1;i<=b[0];i++)
		a[i]=d*b[i];
	for(i=1;i<200;i++)
	{
		a[i+1]+=a[i]/10;
		a[i]%=10;
		a[0]=199;
	}
	while(!a[a[0]-1])
		a[0]--;
	for(j=a[0],r=0;j>0;j--)
    {           
            d=r*10+a[j];
            a[j]=d/(n+2);
            r=d%(n+2);
    }
	while(!a[a[0]-1])
		a[0]--;
	return true;
}
int main()
{
	memset(cta,0,sizeof(cta));
	cta[0][1]=1;
	cta[0][0]=1;
	for(int i=1;i<101;i++)
		mul(cta[i],cta[i-1],i-1);
	int n;
	bool flag=false;
	while(cin>>n)
	{
		flag=false;
		for(int i=cta[n][0];i>0;i--)
			if(cta[n][i]!=0||flag)
				{
				cout<<cta[n][i];
				flag=true;
				}
		cout<<endl;
	}
	return 0;
}
	
	


2.2.8 N! again
注意到2009=41×7×7;当N>=41时,N!mod2009值为0;
小于41,递推计算就行
for(int i=1;i<=n;i++)
ans=(ans*i)%2009;






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值