题目来源于:卡码网KamaCoder
题解来源于:GitHub - youngyangyang04/kamacoder-solutions: 卡码网题解全集
34.大鱼吃小鱼
题目描述
现在有 N 条鱼,每条鱼的体积为 Ai,从左到右排成一排。
A 数组是一个排列。 定义一次大鱼吃小鱼的操作为:对于每一条鱼,它在每一次操作时都会吃掉右边比自己小的一条鱼,值得注意的是,在同一次操作中,每条鱼吃掉比自己小的鱼是同时发生的。
举例:假设有三条鱼,体积分别为 [5, 4, 3],在一次操作中,4 吃 3,5 吃 4,最终只剩下 [5] 一条鱼。 问题是,在多少次操作之后,鱼的数量就不会变了。
输入
输入共有两行。
第一行为一个整数 N。
第二行为一个数组,代表鱼的体积。
输出
输出一个非负整数,表示在多少次操作后鱼的数量就不会变了。
样例输入
6
4 3 2 3 2 1
样例输出
2
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @author light
* @Description 大鱼吃小鱼
*
*
* (思路:
* 判断该数组是否是递增数组,如果不是递增数组,则代表发生一次大鱼吃小鱼操作
* 从后向前遍历数组,当前一个数值大于当前数值时,将数值删掉,直到数组递增数组为止
* @create 2023-08-24 10:00
*/
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
List<Integer> list=new ArrayList<>(); //利用list,方便元素删除操作
for (int i = 0; i <n; i++) {
list.add(input.nextInt());
}
int count=0; //记录大鱼吃小鱼的操作数
while(!isIncrease(list)){
for(int i=list.size()-1;i>0;i--){
if(list.get(i)<list.get(i-1)){
list.remove(i);
}
}
count++;
}
System.out.println(count);
}
//判断是否为递增的
private static boolean isIncrease(List<Integer> list) {
for (int i =1; i < list.size(); i++) {
if(list.get(i)<list.get(i-1)){
return false;
}
}
return true;
}
}
35. 打印二维数组
题目描述
给定一个空的二维整型数组 array[n][m],根据下图的填充规则填充该二维数组。
输入
输入包括两个正整数n,m,代表二维整型数组的大小。
输出
按行输出二维整型数组,每个数字后面都有一个空格。
样例输入 复制
4 4
样例输出 复制
1 2 4 7
3 5 8 11
6 9 12 14
10 13 15 16
import java.util.Scanner;
/**
* @author light
* @Description 打印二维数组
*
* 给定一个空的二维整型数组 array[n][m],根据下图的填充规则填充该二维数组。
* @create 2023-08-24 10:03
*/
public class n6 {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int m=input.nextInt();
int[][] nums=new int[n][m];
int count=1;
//从左到右遍历
for (int i = 0; i <m-1; i++) {
int x=0;
int y=i;
while(x!=n&&y!=-1){
nums[x][y]=count++;
x++;
y--;
}
}
//从上到下
for (int i = 0; i <n ; i++) {
int x=i;
int y=m-1;
while(y!=-1&&x!=n){
nums[x][y]=count++;
x++;
y--;
}
}
for (int k = 0; k < n; k++) {
for (int l = 0; l < m; l++) {
System.out.print(nums[k][l]+" ");
}
System.out.println();
}
}
}
36. 网格路径和
题目描述
现有一个 m * n的网格,每个网格上都有一个非零整数,每次只能向下或者向右移动一格,计算从左上开始移动到右下的所有路径上数字的最大和。
输入
输入为一行,代表一个二维数组。
输出
输出一个整数,代表路径上的数字最大和。
样例输入 复制
[[2,3,1],[2,5,3],[4,2,1]]
样例输出 复制
14
import java.util.Scanner;
/**
* @author light
* @Description 网格路径和
*
*
* (思路:动规
* @create 2023-08-24 10:04
*/
public class Main {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
String arrayString = input.next();
int[][] grid = parse2dArray(arrayString);
System.out.println(getMaxValue(grid));
}
private static int getMaxValue(int[][] grid) {
int m=grid.length; //行
int n=grid[0].length; //列
int[][] dp=new int[m][n]; //dp[i][j]代表了从左上角到达格子(i, j)位置的最大路径和。
//初始化dp[0][0]
dp[0][0]=grid[0][0];
//初始化第0列
for (int i = 1; i < m; i++) {
dp[i][0]=dp[i-1][0]+grid[i][0];
}
//初始化第0行
for (int i = 1; i < n; i++) {
dp[0][i]=dp[0][i-1]+grid[0][i];
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}
return dp[m-1][n-1];
}
// 将字符串解析为二维数组
private static int[][] parse2dArray(String arrayString) {
String[] rowsString=arrayString.substring(1,arrayString.length()-2).split("],");
// "[[1,2,3],[2,3,4],[3,4,5]]" -> "[1,2,3", "[2,3,4", "[3,4,5"
int rows=rowsString.length; //行
int cols=rowsString[0].split(",").length; //列
int[][] digital2dArray = new int[rows][cols];
for (int i = 0; i < rows; i++) {
String[] element=rowsString[i].substring(1).split(",");
//"[1,2,3"->1 2 3
//"[2,3,4"->2 3 4
//"[3,4,5"->3 4 5
for (int j = 0; j < cols; j++) {
digital2dArray[i][j]=Integer.parseInt(element[j]);
}
}
return digital2dArray;
}
}