A Fibonacci
题目描述
 定义一个数列f(i) = f(i-1)+f(i-2), f(0) = 0, f(1) = 1.
 求f(n) mod (1e9+7)
输入数据
 一个正整数n,n<=1e5
输出数据
 f(n) mod (1e9+7)
-  标准斐波那契问题,可以递归可以循环;可以数组保存可以直接变量保存 
-  使用递归会超时 
-  注意mod(1e9). 
题解:
#include<stdio.h>
int main(){
 long int n[100001],i,N;
 scanf("%d",&N);
 n[0]=0;n[1]=1;
 for(i=2;i<=N;i++){
  n[i]=(n[i-1]+n[i-2])%1000000007;
 }
 printf("%d\n",n[N]);
}
F 楼梯
题目描述
 楼梯有n阶,可以一步上一阶、两阶或三阶,问有多少种不同的走法
 由于答案很大,mod(1e9+7)输出
输入数据
 一个正整数n,代表楼梯的阶数,n<=1000000
输出数据
 方案数
样例输入
 3
 样例输出
 4
有n阶(n>3)楼梯时,方案数=f(n-1)+f(n-2)+f(n-3)
 即在前面三种情况的所有方案数下再走1、2、3阶楼梯。
题解
#include<stdio.h>
int main(){
 long int n[4],i,N,x;
 scanf("%d",&N);
 n[0]=0;n[1]=1;n[2]=2;n[3]=4;
 if(N<4) x=n[N];
 else
  for(i=4;i<=N;i++){
   x=(n[1]+n[2]+n[3])%1000000007;
   n[1]=n[2];
   n[2]=n[3];
   n[3]=x;
  }//递归
 printf("%d\n",x);
 return 0;
}
C 汉诺塔移动次数
题目描述
   给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的。现要将这些圆盘移到C柱上,在移动过程中可放在B柱上暂存。要求:
(1)每次只能移动一个圆盘;
(2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;
任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。
输入数据
 输入为一个正整数 n, 表示在 A 柱上放有 2n 个圆盘。
 输出数据
 输出文件hanoi.out仅一行,包含一个正整数,为完成上述任务所需的最少移动次数 An 。
-  找到递归关系 A(n)=2*A(n-1)+2 
-  A(n)的结果可能非常大,远超long long int,所以换python或者Java做吧。java可以用BigInteger类 
n=int(input())
a=2
for i in range(1,n):
  a=2*a+2
print(a)
C 最小公倍数和最大公约数
题目描述
   输入二个正整数x0,y0(2≤x0≤100000,2≤y0≤1000000),求出满足下列条件的P、Q的个数。
   条件:1.P、Q是正整数
      2.要求P、Q以xO为最大公约数,以yO为最小公倍数。
   试求,满足条件的所有可能的两个正整数的个数。
输入数据
 两个正整数
 输出数据
 满足条件的所有可能的两个正整数的个数
 样例输入
 3 60
 样例输出
 4
 样例说明
 说明:(不用输出)此时的 P  Q 分别为:
             3 60
             15 12
             12 15
             60  3
 所以,满足条件的所有可能的两个正整数的个数共4种
分析:设两个整数为:A=k1x0,B=k2x0;k1、k2是互质正整数(因为x0是最大公约数);k1k2=y0/x0(x0y0=A*B:最小公倍数和最大公约数的关系)
- 从1到 y 0 / x 0 \sqrt{y0/x0} y0/x0遍历k1,若k2为整数且k1、k2最大公约数为1,则计数器加一。
#include <stdio.h>
#include<math.h>
int gcd(int a,int b){
 	if(b)
  		return gcd(b,a%b);
 	else
  		return a;
}
int main(){
	 int x0,y0,k1,k2,count=0,t;//k1<k2
	 scanf("%d%d",&x0,&y0);
	 if(y0%x0==0){
	  	t=y0/x0;
	 for(k1=1;k1<sqrt(t);k1++){
	    if(t%k1==0){
	    	k2=t/k1;
	    	if(gcd(k2,k1)==1)
	     		count+=2;
   		}  
  	}
 }
 printf("%d",count);
}
E 特殊质数
题目描述
 农民约翰的母牛总是生产出最好的肋骨。你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们。
 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数字都组成一个质数,举例来说:
 7 3 3 1
 全部肋骨上的数字 7331是质数;三根肋骨 733是质数;二根肋骨 73 是质数;当然,最后一根肋骨 7 也是质数。
7331 被叫做长度 4 的特殊质数。
 写一个程序对给定的肋骨的数目 N (1< =N< =8),求出所有的特殊质数。数字1不被看作一个质数。
输入数据
 单独的一行包含 N 。
 输出数据
 按顺序输出长度为 N 的特殊质数,每行一个。
 并按大小顺序排列(从小到大).
 样例输入
 4
 样例输出
 2333
 2339
 2393
 2399
 2939
 3119
 3137
 3733
 3739
 3793
 3797
 5939
 7193
 7331
 7333
 7393
这题是抄的
 总体做法还是比较暴力的。
- 写一个判断是否为质数的函数
- 写一个递归搜索前x位都是质数的数
例:对于四位数x3x2x1x0,
 首先确定x3只能是2,3,7,5,9,然后选出
 x3x2是质数的解,再从中找x3x2x1是质数的情况,以此类推。sum保存当前判断的数。
题解:
#include<stdio.h>
int n,js,ans[100000];
int judge_prime(int x){
    if(x<=1)return -1;
    for(int i=2;i*i<=x;i++){
        if(x%i==0)return -1;
    }
    return 1;
}
void dfs(int sum,int x){
    if(x==n){
        printf("%d\n",sum);
        return ;
    }
    for(int i=1;i<=9;i+=2){
        if(judge_prime(sum*10+i)==1){
            dfs(sum*10+i,x+1);
        }
    }
}
int main(){
    scanf("%d",&n);
    dfs(2,1);dfs(3,1);dfs(5,1);dfs(7,1);
    return 0;
}
D 简单背包
题目描述
 李老师正准备暑假旅行,他有一个容量为L的行李箱和n个物品(n不超过20),每个物品都有自己的体积,物品可以放入行李箱,但行李箱中物品的总体积不能超过行李箱容量,李老师现在想知道他有多少种携带物品的方案(一个物品都不带也算一种方案)
输入数据
 第一行为两个正整数n和L,分别代表物品总数和行李箱容量,n<=20,L<=1e9 接下来一行为n个正整数vi,代表第i个物品的体积,vi<=1e8
输出数据
 方案数
样例输入
 3 10
 2 4 5
 样例输出
 7
0-1背包,暴力搜索,遍历所有2^n种可能。递归树为完全满二叉树。
- 现在只在遍历到满二叉树的叶子节点时判断是否能装进背包,似乎可以优化,提前判断,提高效率
题解:
#include<stdio.h>
int count;
void fullbitree(int curV,int curN,int L,int n,int v[]){
 if(curN==n){
    if(curV<=L)
    count++;
    return;
 }
 fullbitree(curV,curN+1,L,n,v);
 fullbitree(curV+v[curN],curN+1,L,n,v);
}
int main(){
    int v[20],L,n;
    scanf("%d%d",&n,&L);
    for(int i=0;i<n;i++)
        scanf("%d",&v[i]);
    count=0;
    fullbitree(0,0,L,n,v);
    printf("%d\n",count);
}










