A - Fibbonacci Number
题解:求斐波那契数列(注意:开 long long )
#include <iostream>
using namespace std;
long long f[60];
//打表
void init()
{
f[0]=0;
f[1]=1;
for (int i=2;i<=50;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
int n;
init();
while (~scanf("%d",&n))
{
if (n==-1)
break;
printf("%lld\n",f[n]);
}
return 0;
}
B - 神、上帝以及老天爷
题意:有n为宾客,以及写着每位宾客名字的纸条,每位宾客从所有写着名字的纸条中不放回的抽取一张,问每位宾客抽到的纸条上的名字都不是自己名字的概率(用百分号形式表示)
题解:假设有n为宾客,每个纸条按照宾客抽取的顺序进行编号,第一位宾客从剩余的n-1个帽子抽取了第k个纸条,而k有n-1种可能性,恰好第k位宾客也抽取到第1为宾客的纸条,,所以此时f(n)=(n-1)*f(n-2);但是如果第k为宾客没有抽取到第1张纸条,则f(n)=(n-1)*f(n-1)
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
long long a[25];
long long b[25];
//打表递推公式f(n)=(n-1)*f(n-1)+(n-1)*f(n-2)
void init1()
{
a[1]=0;
a[2]=1;
for (int i=3;i<=20;i++)
a[i]=(i-1)*(a[i-1]+a[i-2]);
}
//打表,n个取纸条,所有的可能性
void init2()
{
b[0]=b[1]=1;
b[2]=2;
for (int i=3;i<=20;i++)
b[i]=b[i-1]*i;
}
int main()
{
int n,m;
init1();
init2();
scanf("%d",&n);
while (n--)
{
scanf("%d",&m);
printf("%.2lf%%",a[m]*1.0/b[m]*1.0*100);
puts("");
}
return 0;
}
C - 母猪的故事
题意: ACBoy要养猪,每头猪在出生后的第二天开始以后每天都会生下一头猪,而且生下的都是母猪,但是在一头猪生下第二头猪的后,会被卖到超市,问在第n天会有多少头猪
题解: 递推
天数 | 年龄为1 | 年龄为2 | 年龄为3 | 总的数量 |
---|---|---|---|---|
1 | 1 | 0 | 0 | 1 |
2 | 1 | 1 | 0 | 2 |
3 | 2 | 1 | 1 | 3 |
4 | 3 | 2 | 1 | 5 |
5 | 5 | 3 | 2 | 8 |
6 | 8 | 5 | 3 | 13 |
某天年龄为1的猪的数量为前一天猪的数量的总量,年龄为2的猪的数量为前一天年龄为1的猪的数量,年龄为3的猪的数量为前一天年龄为2的猪的数量(被卖入超市不计数)
//解法一:打表
#include <iostream>
using namespace std;
long long f[21];
void init()
{
f[1]=1;
f[2]=2;
for (int i=3;i<=20;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
int n;
init();
int m;
scanf("%d",&m);
while (m--)
{
scanf("%d",&n);
printf("%lld\n",f[n]);
}
return 0;
}
//解法二:递归
#include <iostream>
using namespace std;
long long f[21];
long long init(int m)
{
if (m==1)
return 1;
if (m==2)
return 2;
return init(m-1)+init(m-2);
}
int main()
{
int n;
int m;
scanf("%d",&m);
while (m--)
{
scanf("%d",&n);
printf("%lld\n",init(n));
}
return 0;
}
D - 下沙的沙子有几粒?
题意: 告诉你H的数量和D的数量,问有H D有多少种排列的顺序使得,从左开始数H的数量始终大于等于D的数量,例如3个H和1个D,HHHD,HHDH,HDHH ,有三种排列方式
题解: 当D的数量n大于H的数量m时,不存在这种排列。a[m][n]=a[m-1][n]+a[m][n-1],假设3个H和2个D是由2个H和2个D还有3个H一个D推来的,2个H和2个D总共有HDHD,HHDD两种排列,3个H和一个D总共有HDHH,HHDH,HHHD三种排列,然后在HDHD,HHDD的后面添加一个H就是2种排列,在HDHH,HHDH,HHHD的后面添加一个D就有3种方案,所以总共就是5种方案(其它的添加方法都是重复的)
#include<stdio.h>
#include<string.h>
int main()
{
long long a[21][21];
int i,j,m,n;
memset(a,0,sizeof(a));//首先全部初始化为0
for(i=0; i<=20; i++)
a[i][0]=1;//当n为0的时候无论吗取何值都是1
for(i=1; i<=20; i++)
for(j=i; j<=20; j++)
a[j][i]=a[j-1][i]+a[j][i-1];
while(scanf("%d%d",&m,&n)!=EOF)
{
printf("%lld\n",a[m][n]);
}
return 0;
}
E - 算法:骨牌铺方格
题解: n代表长方形方格的长度,当第一个骨牌竖着放入长方形方格中,第一个骨牌已经固定,长方形方格还剩2×(n-1)的空间,则F(n)=F(n-1);当第一,二张骨牌横着放入长方形方格,长方形方格还剩2×(n-2)的空间,则F(n)=F(n-2)。所以根据开头放骨牌的方式,F(n)=F(n-1)+f(n-2)。(此题不可以用递归方式写,递归的时间复杂度太高了,会超时!)
#include<stdio.h>
#include<string.h>
long long f[60];
void init()
{
f[1]=1;
f[2]=2;
for (int i=3;i<=50;i++)
f[i]=f[i-1]+f[i-2];
}
int main()
{
int n;
init();
while (~scanf("%d",&n))
{
printf("%lld\n",f[n]);
}
return 0;
}
F - 蟠桃记
题解: 递推F(n-1)=( F(n)+1 )*2
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <stack>
using namespace std;
int main()
{
int n;
while (~scanf("%d",&n))
{
int ans=1;
while (--n)
{
ans=(ans+1)*2;
}
printf("%d\n",ans);
}
return 0;
}
H - Sum of Consecutive Prime Numbers
题意: 给定一个10000以内的数,如果这个数字可有几个连续的素数的相加得到,问这样的连续的素数有几组
题解: 最笨的方法,先把所有的素数打表找出来,然后跑两层循环找
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=1e4+7;
int prime[N];
void GetPrime()
{
memset(prime,0,sizeof(prime));
for (int i=2;i<N;i++)
{
if (prime[i]==0)
prime[++prime[0]]=i;
for (int j=1;j<=prime[0]&&prime[j]<=N/i;j++)
{
prime[prime[j]*i]=1;
if (i%prime[j]==0)
break;
}
}
}
int main()
{
int n;
GetPrime();
while (~scanf("%d",&n)&&n)
{
int sum=0, ans=0;
for (int i=1;i<=prime[0];i++)
{
sum=0;
for (int j=i;j<=prime[0]&&sum<n;j++)
{
sum+=prime[j];
if (sum==n)
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
I - 不容易系列之二
题解: 和蟠桃记一样递推,简单的数学题
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=1e4+7;
int prime[N];
int a[35];
void init()
{
a[0]=3;
for (int i=1;i<=30;i++)
{
a[i]=(a[i-1]-1)*2;
}
}
int main()
{
int n,m;
init();
scanf("%d",&n);
while (n--)
{
scanf("%d",&m);
printf("%d\n",a[m]);
}
return 0;
}