测试练习 Hanoi问题
Description
如果将课本上的Hanoi塔问题稍做修改:仍然是给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次?
例如N=5,M=2时,可以分别将最小的2个盘子、中间的2个盘子以及最大的一个盘子分别看作一个整体,这样可以转变为N=3,M=1的情况,共需要移动7次。
Input
输入描述:
输入数据仅有一行,包括两个数N和M(0<=M<=N<=8)
Output
输出描述:
仅输出一个数,表示需要移动的最少次数
解题思路
对于N个盘子、3根柱子且每次只能挪动一个盘子,设总的挪动次数为fn,则有对于N个盘子、3根柱子且每次只能挪动一个盘子,则有f(n)=2*f(n-1)+1,f(1)=1,解得f(n)=2^n-1.
由题可知:可以一次性挪动M个盘子,N个盘子可以看做N/M(向上取整)个大盘子,则为2^n/m-1.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
if (n%m==0) {
n/=m;
}
else {
n=n/m+1;
}
int num = (int) (Math.pow(2, n)-1);
System.out.println(num);
scanner.close();
}
}
视频学习
蓝桥杯经典算法第一讲递归与循环
https://www.bilibili.com/video/BV1ty4y117go/?p=1
学习心得
- 循环改递归的关键是逻辑的相似性
- 递归调用仅仅是被调函数恰为主调函数
- 每次调用的层次不同
- 要注意返回的次序
对应练习 最长公共子序列问题
问题描述
找出字符串S1和字符串S2的最长公共子序列。
输入格式
输入包含字符串S1,字符串S2。
输出格式
输出一行,包含一个字符串,表示字符串S1和字符串S2的最长公共子序列。
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
static char[] S1 = scanner.next().toCharArray();
static char[] S2 = scanner.next().toCharArray();
public static void main(String[] args) {
System.out.println("S1和S2的最长公共子序列的长度为:"+lcsLength(0,0));//递归
}
private static int lcsLength(int i,int j){
if(i>=S1.length||j>=S2.length)
return 0;//越界返回
else if(S1[i]==S2[j])
return lcsLength(i+1,j+1)+1;//若字符相同坐标加一向下寻找
else
return Math.max(lcsLength(i+1,j),lcsLength(i,j+1));//向下递归遍历每个字符寻找相同字符
}
}