蓝桥杯31天冲刺之八 [java]

文章目录

  • 神奇的算式
  • 缩位求和
  • 积木大赛

神奇的算式

蓝桥杯31天冲刺之八 [java]_第1张图片

题目链接:https://www.lanqiao.cn/problems/700/learning/

这个题首先需要想出来怎样去得到四位数的组合,开始想的是4个for循环然后得到四个不同的数字再去组合,但是感觉这样有点蠢,然后就换成了现在这种,遍历所有四位数然后筛选出四位数字都不同的再进行判断

分为两种情况

  • 一位数与三位数乘,我选择的是第一位与后三位乘,这样可以确保没有重复并且不会有漏掉的,例如:1483,4831,4813,4183
  • 两位数相乘,这个可能会有重复的情况,例如2187与8721,我使用repeatSet去记录是不是已经处理过这种情况,例如在处理2187的时候会计算21和87的乘积,这时候在set中加入8721,具体参看44行的式子,然后在计算二位数乘法的时候先看看有没有这个数,如果有就说明已经计算过了,直接跳过去看下一个

至于抽了这两个方法主要是为了保持代码的简洁易懂,在写代码的时候要求自己不仅要写出来,并且质量也要高,如果写完过一阵自己都不知道什么意思,那别人怎么能看的懂呐?

package daily;

import java.util.ArrayList;
import java.util.HashSet;

/**
 * https://www.lanqiao.cn/problems/700/learning/
 * 
 * @author Jia
 *
 */
public class day3_15_1 {
	public static void main(String[] args) {
		HashSet<Integer> repeatSet = new HashSet<>();// 用于判断第二种情况是不是重复算了
		int ans = 0;

		for (int i = 1000; i < 9999; i++) {
			// 判断这个数四位是否相同
			ArrayList<Integer> list = getList(i);
			// 当list大小不等于4是表示肯定有重复的数字
			if (list.size() != 4) {
				continue;
			}

			// 情况1 一位数与三位数
			int num1 = i / 1000; // 第一位数字
			int num2 = i % 1000; // 后三位数字
			int mult = num1 * num2;
			ArrayList<Integer> tempList = getList(mult);
			if (judgeListEqual(list, tempList)) {
				ans++;
			}

			// 情况2 两个两位数
			if (repeatSet.contains(i)) {
				continue;
			}
			num1 = i / 100; // 前两位数字
			num2 = i % 100; // 后两位数字
			mult = num1 * num2;
			tempList = getList(mult);
			if (judgeListEqual(list, tempList)) {
				ans++;
				repeatSet.add(num2 * 100 + num1);
			}
		}
		System.out.println(ans);
	}

	/**
	 * 将传入的数字拆分成个位数,如果有相同的数字,则返回的数组长度小于4
	 * 
	 * @param j
	 * @return
	 */
	private static ArrayList<Integer> getList(int j) {
		ArrayList<Integer> list = new ArrayList<>();
		while (j > 0) {
			if (list.contains(j % 10)) {
				break;
			}
			list.add(j % 10);
			j /= 10;
		}
		return list;
	}

	/**
	 * 判断两个数组是否包含相同的元素
	 * 
	 * @param list
	 * @param tempList
	 * @return
	 */
	private static boolean judgeListEqual(ArrayList<Integer> list, ArrayList<Integer> tempList) {
		if (list.size() != tempList.size()) {
			return false;
		}
		for (int i = 0; i < list.size(); i++) {
			if (!tempList.contains(list.get(i))) {
				return false;
			}
		}

		return true;
	}
}

缩位求和

蓝桥杯31天冲刺之八 [java]_第2张图片

题目链接:https://www.lanqiao.cn/problems/181/learning/

这个题直白点说就是把所有位的值加起来,直到最后得到的值在0-10之间为止

这里需要注意的就是输入最多有1000位,因此只能用string去读了,读进来后在while循环中一直进行加法,直到长度为1为止

package daily;

import java.util.Scanner;

/**
 * https://www.lanqiao.cn/problems/181/learning/
 * 
 * @author Jia
 *
 */
public class day3_15_2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next();// 因为读进来的最大有1000位,所以只能用string存了
		sc.close();

		while (str.length() != 1) {
			int temp = 0;// 这里可以定义为整数,1000位全为9加起来也才9000,不会越界
			for (int i = 0; i < str.length(); i++) {
				temp += str.charAt(i) - '0';
			}
			str = Integer.toString(temp);// 转化成string继续循环
		}
		System.out.println(str);
	}
}

积木大赛

蓝桥杯31天冲刺之八 [java]_第3张图片

题目链接:https://www.lanqiao.cn/problems/384/learning/

这个题的题目实在是太难懂了,最后还是看了别人的题解才看懂题,这个大厦其实不是一个大厦,可以看成是有n个大厦横向挨着排在一起,然后每一个大厦的高度是 h i h_i hi,要求建造这些大厦,并且所需操作次数最小。大概是下面这样

蓝桥杯31天冲刺之八 [java]_第4张图片

这个题是一个很明显的贪心问题,我们如果要建造一个大厦,那么肯定是在盖一层的时候把挨着的全部盖过去,例如在盖第二层的时候我们需要建两次,一次是 [ 0 , 2 ] [0,2] [0,2],一次是 [ 4 , 4 ] [4,4] [4,4],所以我们只需要在后一栋比前一栋高的时候,统计后一层和前一层高度的差值即可,因为下面的在盖前面的时候也给他盖好了,当后一栋比前一栋低的时候就不管了。可以先对照着上图自己模拟一下这个过程,理解了之后再写代码就会简单很多

package daily;

import java.util.Scanner;

/**
 * https://www.lanqiao.cn/problems/384/learning/
 * 
 * @author Jia
 *
 */
public class day3_15_3 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] height = new int[n];// 记录大厦的高度
		for (int i = 0; i < n; i++) {
			height[i] = sc.nextInt();
		}
		sc.close();

		int ans = height[0];
		for (int i = 1; i < height.length; i++) {
			if (height[i] > height[i - 1]) {
				ans += height[i] - height[i - 1];// 如果后一个大厦比前一个大厦高那么就加上两个大厦的差值
			}
		}
		System.out.println(ans);
	}
}

你可能感兴趣的:(蓝桥杯,java,蓝桥杯,算法)