📢📢📢哈喽哈喽 ~ 我又来了 ,今天没早八,心里乐开花😄😄
🍓🍓星期计算🍓🍓
📄问题描述
🍓题目很简单就是求20的22次方看对7取余后是多少,就说明在星期六的基础上过了几天,自己口算一下知道是星期几了。群里大佬们用的方法也多种多样,这里我用的是快速幂,这道题当作是我复习快速幂了。
看到的同学也可以学习一下这个快速幂模板,跟着梗佬学的,不是小菜鸡我自己写的嗷😃
📗参考代码
public class Main {
public static void main(String[] args) {
long a = qmi(20, 22, 7);
System.out.println(a);//记得这个输出是指在星期六的基础上过了几天
}
//快速幂模板 求a^b%p
private static long qmi(long a, long b, long p) {
//这里对p取余是考虑到怕可能为1的情况 如果p为1 那就没有继续下去的必要了
long res = 1 % p;
while (b > 0) {
//b & 1 就是看b的二进制最后一位是否为1(为1说明b是奇数)是的话b&1结果为1 否则为0
if ((b & 1) == 1) res = res * a % p;
a = (a * a) % p; //快速幂核心操作——扩底
b >>= 1; //快速幂核心操作——降幂
}
return res;
}
}
🍉🍉考勤刷卡🍉🍉
📄问题描述
❓思路分享
🍉要去重而且排序,我们第一个想到的就是一个数据结构,那就是TreeSet!我们只需要将员工序号分别放到TreeSet里面,然后等待它为我们去重 + 排序咯,不得不说真的是功能强大,太香啦~😍
🍉不过群里大佬还有用TreeMap来实现的,去学习了一下才知道:
TreeMap是一个基于key有序的key value散列表,也就是说TreeMap也可以根据key值来排序。
另外顺便总结了几种遍历输出的方法,在代码中给大家注释了,可以留意一下奥!
📗参考代码
TreeSet实现
import java.io.*;
import java.util.Iterator;
import java.util.TreeSet;
public class 考勤刷卡 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n = Integer.parseInt(br.readLine());
TreeSet<Integer> set = new TreeSet<>();
for (int i = 0; i < n; i++) {
String[] s = br.readLine().split(" ");
set.add(Integer.parseInt(s[1]));
}
for (Integer i : set) System.out.println(i); //增强for遍历
Iterator<Integer> it = set.iterator(); //使用迭代器 Iterator遍历
while (it.hasNext()) System.out.println(it.next());
}
}
TreeMap实现 含map的几种遍历方法
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class 考勤刷卡_TreeMap {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws IOException {
int n = Integer.parseInt(br.readLine());
Map<Integer, String> map = new TreeMap<>();
for (int i = 0; i < n; i++) {
String[] s = br.readLine().trim().split(" ");
String time = s[0];
int id = Integer.parseInt(s[1]);
map.put(id,time);
}
//增强for循环遍历 底层实现是迭代器
for(Object i : map.keySet()) System.out.println(i);
//通过entrySet实现遍历
Set<Map.Entry<Integer,String>> entrySet = map.entrySet();
for (Map.Entry entry : entrySet){
System.out.println(entry.getKey());
}
//通过Iterator迭代器实现遍历
Iterator<Map.Entry<Integer,String>> entryIterator = map.entrySet().iterator();
while(entryIterator.hasNext()){
Map.Entry<Integer,String> entry = entryIterator.next();
System.out.println(entry.getKey());
}
//通过lambda表达式实现遍历
map.forEach((id,time) ->{
System.out.println(id);
});
}
}
🍅🍅卡牌🍅🍅
📄问题描述
🍅
❓思路分享
🍅题意大概就是一套牌由n种不同的牌组成(1-n),每种牌初始有若干张(ai),也给定了每种牌最多可以添多少张(bi),能添进来牌的总个数也有限制(m),要求出最多可以凑出多少套牌。
🍅🍅假设最多可以凑够x套牌,那么也1到x套牌也是能凑够的,超过x套就凑不够了,这就满足了二段性,后一段是我们不要的,前一段是我们要的。
详细的思路我注释在了代码里面,请移步。👇
📗参考代码
import java.io.*;
public class 卡牌 {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static int N = 200010;
static int[] a = new int[N];
static int[] b = new int[N];
static long m, n;
public static void main(String[] args) throws IOException {
String[] s = br.readLine().split(" ");
n = Long.parseLong(s[0]);
m = Long.parseLong(s[1]);//供添加的卡牌总数量
s = br.readLine().split(" ");
for (int i = 1; i <= n; i++) {
a[i] = Integer.parseInt(s[i - 1]);//i种卡牌初始数量
}
s = br.readLine().split(" ");
for (int i = 1; i <= n; ++i) {
b[i] = Integer.parseInt(s[i - 1]);//限制添加的最大数量
}
int l = 0, r = 2 * N;
while (l < r) {
int mid = l + r + 1 >> 1;
//如果能凑够mid套牌 那么mid作为左边界继续查找最大的可以凑出的卡牌套数
if (check(mid)) l = mid;
else r = mid - 1;
}
System.out.println(l);
}
//判断能否凑够x套牌
static boolean check(int x) {
long v = m;
for (int i = 1; i <= n; ++i) {
//当第 i 种牌的起始数量已经比我们要尝试的套数大的时候,不用再给这种牌添,跳过
if (a[i] >= x) continue;
//当给第i种牌添加了最大限制b[i]张仍不够x时,那么说明x套是凑不成的
if (a[i] + b[i] < x) return false;
//能凑够x的情况 并且剩下供添加的卡牌数量足够时 消耗供添加的卡牌数量 否则凑不成
if (a[i] + b[i] >= x && v >= x - a[i]) v -= (x - a[i]);
else return false;
}
//循环结束 说明i种卡牌都能凑够x张 返回true
return true;
}
}
🍆🍆最大子矩阵🍆🍆
才疏学浅,不会写,等我水平到了一定补上! ✊