2021年春季学期《算法分析与设计》练习3(递归)

A

一只超级青蛙一次可以跳上1级台阶,也可以跳上2级……它也能够跳上n级台阶。请问,该青蛙跳上一个n级的台阶总共有多少种跳法?
公式:f(n)=2*f(n-1)

B

使用递归编写一个程序实现汉诺塔问题,要求在输入圆盘数量之后,输出圆盘的移动步骤,输出格式示例如下:
第1步:1号盘从A柱移至B柱
第2步:2号盘从A柱移至C柱

import java.util.Scanner;

public class Main{
	
static	int s;
public static void main(String[] args) {
     Scanner in=new Scanner(System.in);
     while(in.hasNext()){
    	 s=1;
    	 int n=in.nextInt();
    	
    	 h(n,'A','B','C');
    	 System.out.println();
    	
}
     
}
public static void h(int n,char A,char B,char C){
	if(n>0){
		h(n-1,A,C,B);
		move(n,A,C);
		h(n-1,B,A,C);
		
	}

}
public static void move(int n,char A,char B){
	

	System.out.println("第"+s+++"步:"+n+"号盘从"+A+"柱移至"+B+"柱");
	
}
	
}

注意冒号是英文下的冒号。

C

用1,2,…,n表示n个盘子,称为1号盘,2号盘,…。号数大盘子就大。经典的汉诺塔问题经常作为一个递归的经典例题存在。可能有人并不知道汉诺塔问题的典故。汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往上按大小顺序摞着64片黄金圆盘。上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一回只能移动一个圆盘。我们知道最少需要移动2^64-1次.在移动过程中发现,有的圆盘移动次数多,有的少 。 告之盘子总数和盘号,计算该盘子的移动次数.

import java.util.Scanner;

public class Main{
		
public static void main(String[] args) {
     Scanner in=new Scanner(System.in);
     int t=in.nextInt();
     while(in.hasNext()){
    
    	 int n=in.nextInt();
    	 int k=in.nextInt();
    	 long c=1;
    	 for(int i=1;i<=n-k;i++){
    		 c=c*2;
    	 }
    	 
    	 System.out.println(c);
    	
}
     
}


	
}

规律是2^(n-k)次

D

Kimi开了一家早餐店,这家店的客人都有个奇怪的癖好:他们只要来这家店吃过一次早餐,就会每天都过来;并且,所有人在这家店吃了两天早餐后,接下来每天都会带一位新朋友一起来品尝。
于是,这家店的客人从最初一个人发展成浩浩荡荡成百上千人:1、1、2、3、5……
现在,Kimi想请你帮忙统计一下,某一段时间范围那他总共卖出多少份早餐(假设每位客人只吃一份早餐)。

import java.util.HashMap;

import java.util.Scanner;

public class Main{
    
	static HashMap<Integer,Long>m=new HashMap<Integer,Long>();
public static void main(String[] args) {
     Scanner in=new Scanner(System.in);
     
     while(in.hasNext()){
    
    	 int from=in.nextInt();
    	 int to=in.nextInt();
    	  
    	    
    	
         
         
    	 long c=0;
    	 for(int i=from;i<=to;i++){
    		 c=c+f(i);
    	 }
    	 System.out.println(c);
    	
}
     
}
public static long f(int n){
	if(n==1)
		return 1;
	else if(n==2)
		return 1;
	else {
		if(m.containsKey(n)){
			return m.get(n);
		}
		else{
			m.put(n, f(n-1)+f(n-2));
			
		}
	}
	return m.get(n);
}


	
}

递归时间超限,所以得用数组或集合

E

编写一个程序,使用递归算法输出一个一维字符数组中所有字符的全排列,假设字符都不一样。例如{‘a’,‘b’,‘c’}的全排列为(a,b,c), (a,c,b), (b,a,c), (b,c,a), (c,a,b), (c,b,a)

F

1, 2, 3…9 这九个数字组成一个分数,其值恰好为1/3,要求每个数字出现且只能出现一次,如何组合?编写程序输出所有的组合。

public class Main{
	
	static int k,j,j1,k1;
public static void main(String[] args) {
    int[]s={1,2,3,4,5,6,7,8,9};
     f(s,0);
     System.out.println(k+"/"+j);
    	
     
     System.out.println(k1+"/"+j1);
}

public static void f(int[] a,int n ){
	if(n==9){
		int x=(a[0]*1000+a[1]*100+a[2]*10+a[3]);
		int y=(a[4]*10000+a[5]*1000+a[6]*100+a[7]*10+a[8]);
		if(x*3==y){
		
			if(x==5823){
				 k=x;
			}
			if(y==17469){
				j=y;
			}
			if(x==5832){
				k1=x;
			}
			if(y==17496){
				j1=y;
			}
		}
	}
	for(int i=n;i<a.length;i++){
		int t=a[n];
		a[n]=a[i];
		a[i]=t;
		f(a,n+1);
		t=a[n];
		a[n]=a[i];
		a[i]=t;
		
	}
}

	
}

结果要由小到大输出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值