题目来源于:卡码网KamaCoder
题解来源于:GitHub - youngyangyang04/kamacoder-solutions: 卡码网题解全集
求和
题目描述
输入两个整数n, m,从数列 1, 2, ..., n 中随意取几个数字,使其和等于 m,要求将所有的可能的组合列出来。
输入
输入只有一行,第一个数字为 n,第二个数字为 m。
输出
按每个组合的字典序排列输出,每行输出一种组合。
样例输入
5 5
样例输出
1 4
2 3
5
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @author light
* @Description 求和
* @create 2023-08-31 19:06
*/
public class n10 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int m=input.nextInt();
getResult(m, n);
}
public static List<Integer> path=new ArrayList<>();
public static void getResult(int m,int n){
backtracking(m,n,0,1);
}
private static void backtracking(int m, int n,int sum, int startIndex) {
if(sum>m){
return;
}
if(sum==m){
for (int i = 0; i < path.size()-1; i++) {
System.out.print(path.get(i)+" ");
}
System.out.println(path.get(path.size() - 1));
}
for (int i = startIndex; i <=n&&sum+i<=m; i++) {
path.add(i);
sum+=i;
backtracking(m,n,sum,i+1);
path.remove(path.size()-1);
sum-=i;
}
}
}
到达目的地最短距离
题目描述
在数轴上,有一个点(坐标为x)可以移动。
这个点遵循移动规则如下:
1. 在数轴上向前移动一格,即 x = x + 1
2. 在数轴上向后移动一格,即 x = x - 1
3. 在数轴上移动到当前位置数值的两倍:即 x = x * 2
现这个点在原点,求将这个点移动到位置 X 所需要的最少移动次数。
输入
输入仅有一个整数,代表位置 X。
输出
输出一个整数,代表最少移动次数。
样例输入
3
样例输出
3
import java.util.Scanner;
/**
* @author light
* @Description 问题: 到达目的地的最短距离
*
* 在数轴上,有一个点(坐标为x)可以移动。
*
* 这个点遵循移动规则如下:
*
* 1. 在数轴上向前移动一格,即 x = x + 1
* 2. 在数轴上向后移动一格,即 x = x - 1
* 3. 在数轴上移动到当前位置数值的两倍:即 x = x * 2
*
* 现这个点在原点,求将这个点移动到位置 X 所需要的最少移动次数。
*
*(思路:动态规划
*
* @create 2023-08-31 19:08
*/
public class n11 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int x=input.nextInt();
System.out.println(getMinDistance(x));
}
private static int getMinDistance(int x) {
if ( x < 2 && x >= 0) {
return x;
}
// 处理 x 为负数的情况
if (x < 0) {
x = -x;
}
//求将这个点移动到位置X所需要的最少移动次数为dp[i]。
int[] dp=new int[x+1];
/*
一、如果当前的位置能够被 2 整除,只有一种走法
从别的位置,通过在数轴上移动到当前位置数值的两倍方式移动过来的。
dp[i] = dp[i / 2] + 1;
二、如果当前的位置不能被 2 整数,有两种走法
1. 通过在数轴上向前移动一格的方式移动过来的
2. 通过在数轴上向后移动一格的方式移动过来的
dp[i] = Math.min(dp[i - 1], dp[(i + 1) / 2] + 1) + 1
第 1 种走法为 dp[i - 1] 不难理解
为什么第 2 种走法会是 dp[(i + 1) / 2] + 1 呢?
因为如果当前位置不能被整除,那么这个位置的后一个位置必定能被整除,能被整除的坐标参考能被整除的走法。
*/
dp[0]=0;
dp[1]=1;
for (int i = 2; i <=x ; i++) {
if(i%2==0){
dp[i]=dp[i/2]+1;
}else {
dp[i]=Math.min(dp[i-1],1+dp[(i+1)/2])+1;
}
}
return dp[x];
}
}