神奇的算式
题目链接: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;
}
}
缩位求和
题目链接: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);
}
}
积木大赛
题目链接:https://www.lanqiao.cn/problems/384/learning/
这个题的题目实在是太难懂了,最后还是看了别人的题解才看懂题,这个大厦其实不是一个大厦,可以看成是有n个大厦横向挨着排在一起,然后每一个大厦的高度是 h i h_i hi,要求建造这些大厦,并且所需操作次数最小。大概是下面这样
这个题是一个很明显的贪心问题,我们如果要建造一个大厦,那么肯定是在盖一层的时候把挨着的全部盖过去,例如在盖第二层的时候我们需要建两次,一次是 [ 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);
}
}