特辣的海藻!9
知识点
LinkedList
在util包下,实现了List和Deque接口,提供了双向链表的实现。
特性:
- 双向链表:每个节点包含数据以及指向前后节点的引用。
- 动态大小:无需预先指定容量,可以动态增长。
- 支持快速插入和删除:在链表头部和尾部插入/删除元素的时间复杂度为O(1)
- 随机访问较慢:访问中间元素的时间复杂度为O(n)
- 线程不安全:多线程环境下需要手动同步
实现List接口方法
- add(E e):在链表尾部添加元素
- add(int index, E element):在指定位置插入元素
- get(int index):获取指定位置的元素
- set(int index, E element):替换指定位置的元素
- remove(int index):移除指定位置的元素
- remove(Object o):移除第一个匹配的元素
- size():返回链表的元素个数
- isEmpty():判断链表的元素个数
- clear():清空链表
- contains(Object o):判断链表是否包含指定元素
- indexOf(Object o):返回指定元素最后一次出现的索引
- toArray():将链表转换为数组
实现Deque接口的方法
- addFirst(E e):在链表头部添加元素
- addLast(E e):在链表尾部添加元素
- offerFirst(E e):在链表头部添加元素(返回布尔值)
- offerLast(E e):在链表尾部添加元素(返回布尔值)
- removeFirst():移除并返回链表头部元素
- removeLast():移除并返回链表尾部元素
- pollFirst():移除并返回链表头部元素
- pollLast():移除并返回链表尾部元素
- getFirst():返回链表头部元素
- getLast():返回链表尾部元素
- peekFirst():查看链表头部元素(不移除)
- peekLast():查看链表尾部元素(不移除)
题
1.四平方和 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
for(int i = 0; i*i <= n; i++) {
for(int j = i; j*j <= n; j++) {
for(int k = j; k*k <= n; k++) {
for(int m = k; m*m <= n; m++) {
if(i*i + j*j + k*k + m*m == n) {
System.out.print(i + " ");
System.out.print(j + " ");
System.out.print(k + " ");
System.out.print(m);
return;
}
}
}
}
}
scan.close();
}
}
用暴力的方法 四层循环一个一个试一下,我的暴力没有全过的关键在于,循环的边界没有优化。
每一个内循环的起点,是上一个循环的当前值,这样可以满足题目的条件 a<=b<=c<=d,然后这样又不会重复搜索已经不可能的值 比如b>c的。终止条件是每一层循环的当前变量的平方小于等于目标值,因为你一个数的平方都已经大于目标值了,四个数的平方和更加大于。
2.卡片 - 蓝桥云课
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int res = 0;
for(int i = 1; ; i++) {
res++;
n -= i;
if(n <= 0)
break;
}
System.out.print(res);
scan.close();
}
}
可以看到n=4:
11 12 13 14 22 23 24 33 34 44 -> 4 + 3 + 2 + 1种组合
n=5:
11 12 13 14 15 22 23 24 25 33 34 35 44 45 55 -> 5 + 4 + 3 + 2 + 1
这不就是等差数列求和吗,找到一个k使得k*(k+1)/2 >= n
3.直线 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
// 线
HashSet<Map<Double, Double>> lines = new HashSet<>();
// 点
List<Map<Integer, Integer>> dot = new ArrayList<>();
for(int i = 0; i < 20; i++) {
for(int j = 0; j < 21; j++) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(i, j);
dot.add(map);
}
}
double x1 = 0, x2 = 0, y1 = 0, y2 = 0;
for(int i = 0; i < dot.size(); i++) {
for(int j = i + 1; j < dot.size(); j++) {
for(HashMap.Entry<Integer, Integer> entry : dot.get(i).entrySet()) {
x1 = entry.getKey();
y1 = entry.getValue();
}
for(HashMap.Entry<Integer, Integer> entry : dot.get(j).entrySet()) {
x2 = entry.getKey();
y2 = entry.getValue();
}
if(x1 == x2 || y1 == y2)
continue;
double k = (y2-y1) / (x2-x1);
double b = (y2*x1 - y1*x2) / (x1-x2);
HashMap<Double, Double> temp = new HashMap<>();
temp.put(k, b);
lines.add(temp);
}
}
System.out.print(lines.size() + 21 + 20);
}
}
用一个HashSe(lines)t存储两点确定的直线,用一个HashMap存储这个网格所有的点,每两个点直接计算斜率,用斜率k和截距b代表一条直线,放到lines中,如果k和b值一样。会自动去重,考的对语法和代码的一个熟练度吧
3.货物摆放 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
long num = 2021041820210418l;
ArrayList<Long> div = new ArrayList<>();
for(long i = 1; i <= Math.sqrt(num); i++) {
if(num % i == 0){
div.add(i);
long n = num / i;
// 如果相等的因子放进去,到时候就容不下第三个因子的位置了!
if(n != i)
div.add(n);
}
}
int res = 0;
for(long a : div) {
for(long b : div) {
for(long c : div) {
if(num == a*b*c)
res++;
}
}
}
System.out.print(res);
}
}
不加思考的暴力肯定会超时 ,这么大的数字。
我们可以发现这个数就是要找可以被整除的三个数的各种组合,那怎么优化呢,那三个数肯定都是这个数的因子嘛,我们遍历他的因子看符不符合条件就好了。(Tips:一个数 i 可以被num整除,那么num/i也是num的因子捏)
4.时间显示 - 蓝桥云课
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
long num = scan.nextLong();
// 转化为秒
num /= 1000;
// 最后一天有多少秒
num = num % (60*60*24);
// 转化为小时
long hour = num / (60*60);
// 转换为秒
long s = num % 60;
// 转换为分钟
long min = num / 60 % 60;
System.out.printf("%02d:%02d:%02d",hour, min, s);
scan.close();
}
}
一天有24小时,一小时有60分钟,一分钟有60秒。所以一天有24*60*60秒。将毫秒转化为秒后,取模可以算出最后这一条有多少秒。
60秒等于1分钟,60分钟等于1小时。所以除两次60可以转换为以小时为单位。
取模60可以得到以秒为单位,这段时间还剩多少秒。
除以60转换为分钟,取模60可以得到转换以分钟为单位后,这天还有多少分钟。
import java.util.Date;
import java.util.Scanner;
import java.text.SimpleDateFormat;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
long num = scan.nextLong();
// 转换为日期
Date date = new Date(num);
// 定义格式化模板
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
// 设定时区
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.print(sdf.format(date));
scan.close();
}
}
5.最少砝码 - 蓝桥云课
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
int res = 0, temp = 0;
while(temp < num) {
temp += Math.pow(3, res);
res++;
}
System.out.print(res);
scan.close();
}
}
这个题目可以抽象成一个三进制的问题,为什么呢?因为每个砝码有三种状态:使用它(1)、不使用它(0)、减去它(把它放在另一边-1)。所以可以想成每个砝码增加都是前面一个砝码的三倍这样增加。其实这道题里面也蕴含着一种贪心的思想。求称出一个数N,从1到N的连续数字的数量。可以转换为用最少的砝码,尽可能的称出最大的重量。
6.航班时间 - 蓝桥云课
import java.util.*;
public class Main {
public static Scanner scan = new Scanner(System.in);
public static int getTime() {
String[] str = scan.nextLine().split(" ");
int h1 = Integer.parseInt(str[0].substring(0,2));
int m1 = Integer.parseInt(str[0].substring(3,5));
int s1 = Integer.parseInt(str[0].substring(6,8));
int h2 = Integer.parseInt(str[1].substring(0,2));
int m2 = Integer.parseInt(str[1].substring(3,5));
int s2 = Integer.parseInt(str[1].substring(6,8));
int day = 0;
if(str.length == 3)
day = Integer.parseInt(str[2].substring(2,3));
int t1 = h1*3600 + m1*60 + s1;
int t2 = h2*3600 + m2*60 + s2;
return t2 - t1 + day*24*60*60;
}
public static void main(String[] args) {
int n = scan.nextInt();
scan.nextLine();
for(int i = 0; i < n; i++) {
int go = getTime();
int back = getTime();
int time = (go + back) / 2;
int hour = time/ 60 / 60;
int min = time / 60 % 60;
int second = time % 60;
System.out.printf("%02d:%02d:%02d\n", hour, min, second);
}
scan.close();
}
}
7.交换瓶子 - 蓝桥云课
import java.util.Scanner;
// 1:无需package
// 2: 类名必须Main, 不可修改
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
//在此输入您的代码...
int n = scan.nextInt();
int[] nums = new int[n+1];
for(int i = 1; i <= n; i++)
nums[i] = scan.nextInt();
int res = 0;
for(int i = 1; i <= n; i++) {
int x = nums[i];
if(x != i) {
res++;
for(int j = 1; j <= n; j++) {
if(i == nums[j]) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
}
}
}
System.out.print(res);
scan.close();
}
}
就无脑模拟啊,如果位置i上面的数字x不等于i,那我们就再遍历一次数组,找到数字i所在的位置,然后交换,记录数字就好。