第十一届蓝桥杯省赛(Java)

在这里插入图片描述

public class 门牌制作 {
	public static void main(String[] args) {
		int ans = 0;
		for (int i = 1; i <= 2020; i++) {
			int num = i;
			while (num != 0) {
				int temp = num % 10;
				if (temp == 2) {
					ans++;
				}
				num /= 10;
			}
		}
		System.out.println(ans);
	}
}

答案:624

在这里插入图片描述
**

  • 首先我没有读懂题
  • 其次我想复杂了
  • 因为我被大数据吓住了
  • 最后我要是冷静下来分析,也不会哭成个死人

**

分析

首先知道这个矩阵有多少行和列,可以打开记事本来看,或者pycharm可以看有多少行和列
或者用代码

在这里插入图片描述

将txt文件的数据全部复制到控制台

Scanner read = new Scanner(System.in);
		String string = "";
		for (int i = 1;; i++) {//i从1 开始
			string = read.nextLine();
			if (string != null) {
				System.out.print(i+" ");
			}
		}

完整代码


import java.util.Scanner;

public class 寻找2020 {
	static int count = 0;

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		String[] str = new String[300];// 知道矩阵有多少行
		for (int i = 0; i < str.length; i++) {
			str[i] = input.nextLine();
		}
		char[][] cs = new char[str.length][str.length];
		for (int i = 0; i < str.length; i++) {
			cs[i] = str[i].toCharArray();
		}
		fun(cs);
		System.out.println(count);
	}

	public static void fun(char[][] cs) {
		int n = cs.length;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				// 行
				if (j + 3 < n) {
					if (cs[i][j] == '2' && cs[i][j + 1] == '0' && cs[i][j + 2] == '2' && cs[i][j + 3] == '0') {
						count++;
					}
				}
				// 列
				if (i + 3 < n) {
					if (cs[i][j] == '2' && cs[i + 1][j] == '0' && cs[i + 2][j] == '2' && cs[i + 3][j] == '0') {
						count++;
					}
				}
				// 左上到右下
				if (i + 3 < n && j + 3 < n) {
					if (cs[i][j] == '2' && cs[i + 1][j + 1] == '0' && cs[i + 2][j + 2] == '2'
							&& cs[i + 3][j + 3] == '0') {
						count++;
					}
				}
			}
		}

	}
}

该题总结:不要看到这么多数据就吓死了,不知道怎么分析!!该画图!!就画图!!画图!!想清楚下标的合法范围,然后统计行、列、左上到右下(看清楚,只有左上到右下,别多算右上到左下)

结果:
在这里插入图片描述

在这里插入图片描述
我写的烂大街的代码。。。。。

public static void main(String[] args) {
		int n = 40;//通过调试,发现n要取大一点,第20行20列才可能被填充
		int[][] arr = new int[n][n];
		arr[0][0] = 1;
		int i = 0, j = 1;
		while (i < n && j < n) {
			while (j != 0 && j < n - 1) {
				if (i == 0) {
					arr[i][j] = arr[i][j - 1] + 1;
				} else {
					arr[i][j] = arr[i - 1][j + 1] + 1;
				}
				i++;
				j--;
			}
			if (i < n && j < n - 1 && i >= 1 && j >= 0) {
				arr[i][j] = arr[i - 1][j + 1] + 1;
				i++;
			} else {
				break;
			}
			while (i != 0 && i < n - 1) {
				if (j == 0) {
					arr[i][j] = arr[i - 1][j] + 1;
				} else {
					arr[i][j] = arr[i + 1][j - 1] + 1;
				}
				i--;
				j++;
			}
			if (i < n - 1 && j < n && i >= 0 && j >= 1) {
				arr[i][j] = arr[i + 1][j - 1] + 1;
				j++;
			} else {
				break;
			}
		}
		for (int[] temp : arr) {
			System.out.println(Arrays.toString(temp));
		}
	}

当然这道题可以推出公式!没想到吧!
分析:我们是从1开始填充这个二维数组,我们要求的位置都是位于反对角线上的,所以所处的(x,y),x=y,可以写成(x,x)。我们要求第n行第n列的值,可以先求出左上部分已经填满的个数,再加上自身所在的行数,即为答案。

  • 那我们怎么求出已经填满的个数呢?
    在这里插入图片描述

我们可以先求出左上部分的个数,我们可以以“斜行”来命名从右上到左下,
在这里插入图片描述
要求第二行第二列的值,就要先填满1斜行、2斜行,即1+2=3,表示前面已经填满了3个数,那么再加上第二行的2,即3+2=5,为答案。
我们可以发现规律,要求某个对角线上的数,先求出已填满的斜行数,累加即为左上部分填满的元素的个数,通过递推得公式:
1+2+3…+2*(n-1),S和=(2n-1)(2n-2)/2,这就是左上部分的已填满的个数。
另外,该对角线所处的行决定了“从已填满的斜行的下一个斜行”,需要填满几个数即走到该位置
所以,

S总=(2n-1)(2n-2)/2+n

答案:761

在这里插入图片描述

我放弃

答案80

在这里插入图片描述

*补充一个字符数组转为String的方法

char[] cs = new char[26];
for (int i = 0; i < 26; i++) {
	cs[i] = (char) ('a' + i);
}
**String str = new String(cs);**
System.out.println(str);

这道题纯推导
在这里插入图片描述

在这里插入图片描述
sum要转型!细节决定成败,不要马虎,越简单越要想清楚

public class 成绩分析 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int[] arr = new int[n];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = input.nextInt();
		}
		int max = arr[0];
		int min = arr[0];
		double sum = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			} else if (arr[i] < min) {
				min = arr[i];
			}
			sum += arr[i];
		}
		System.out.println(max);
		System.out.println(min);
		System.out.printf("%.2f", sum / n);
	//或者 System.out.println(String.format("%.2f", (double) sum / n));
	}
}

在这里插入图片描述

public class 单词分析 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String string = sc.nextLine();
		char[] temp = string.toCharArray();
		int[] count = new int[26];
		for (int i = 0; i < temp.length; i++) {
			count[temp[i] - 'a']++;
		}
		int max = Integer.MIN_VALUE;
		int index = -1;
		for (int i = 0; i < count.length; i++) {
			if (count[i] > max) {
				max = count[i];
				index = i;
			}
		}
		System.out.println((char) ('a' + index));
		System.out.println(max);
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方法一:动态规划

public class 数字三角形 {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int[][] arr = new int[n][n];
		int[][] res = new int[n][n];
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				arr[i][j] = scanner.nextInt();
			}
		}
		res[0][0] = arr[0][0];
		for (int i = 1; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				if (j == 0) {
					res[i][j] = res[i - 1][j] + arr[i][j];
				} else if (i == j) {
					res[i][j] = res[i - 1][j - 1] + arr[i][j];
				} else {
					res[i][j] = Math.max(res[i - 1][j - 1], res[i - 1][j]) + arr[i][j];
				}
			}
		}
		int ans = 0;
		ans = n % 2 == 1 ? res[n - 1][n / 2] : Math.max(res[n - 1][n / 2 - 1], res[n - 1][n / 2]);
		System.out.println(ans);
	}

}

方法二:适合考试时做不出来的动态规划就用dfs

找到所有符合条件的路径之和,并与max作比较

public class 数字三角形2 {
	static int max = -1;
	static HashSet<Integer> dp = new HashSet<>();

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int[][] arr = new int[n][n];
		for (int i = 0; i < arr.length; i++) {
			for (int j = 0; j <= i; j++) {
				arr[i][j] = scanner.nextInt();
			}
		}
		dfs(arr, 0, 0, 0, 0, 0, new boolean[n][n]);// 找出所有符合的路径之和
		// System.out.println(dp);// 查看是否符合案例
		System.out.println(max);
	}

	public static void dfs(int[][] arr, int row, int col, int sum, int left, int right, boolean[][] flag) {
		if (row == arr.length - 1 && Math.abs(right - left) <= 1) {
			// dp.add(sum + arr[row][col]);
			if (sum + arr[row][col] > max) {
				max = sum + arr[row][col];
			}
			return;
		}
		if (row >= arr.length || col >= arr.length) {
			return;
		}
		// 走
		if (!flag[row][col]) {
			flag[row][col] = true;
			dfs(arr, row + 1, col, sum + arr[row][col], left + 1, right, flag);
			dfs(arr, row + 1, col + 1, sum + arr[row][col], left, right + 1, flag);
			flag[row][col] = false;
		}
	}
}

在这里插入图片描述
在这里插入图片描述

方法一:暴力

public class 子串分值和 {
	static char[] cs;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String string = sc.nextLine();
		int sum = 0;
		cs = string.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			for (int j = i + 1; j <= cs.length; j++) {
				sum += func(i, j);
			}
		}
		System.out.println(sum);
	}

	public static int func(int i, int j) {
		HashSet<Character> set = new HashSet<>();
		while (i < j) {
			set.add(cs[i]);
			i++;
		}
		return set.size();
	}
}

这道题若使用subString(),消耗较大,采用传入下标,用set进行统计。
但是只能得一半的分。

方法二:官方解答
在这里插入图片描述
在这里插入图片描述

最后一题放弃

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值