蓝桥杯Java组常用算法与技巧
基本准备与注意
- 考试时长:4小时
- 证件准备:身份证和准考证
- 设置Eclipse的字体大小Windows-preferences–搜索font–双击Colors and Fonts 的Basic的text font-输入15号字体
- 为Eclipse绑定源码:随便进入一个系统类–attach source–关联外部文件(一般为C:\Program Files\Java\jdk1.8.0_261\src.zip)
- Excel的使用:主要就是使用里面的函数:1.先设置格式(开始–数字格式)2.使用函数(公式–查入函数)
- 代码文件尽量放在D盘,防止死机代码文件被系统删除
IO流
借助BufferedReader
写入文件
BufferedWriter bw = new BufferedWriter(new FileWriter("src//data.txt"));
bw.write("hello");
bw.newLine();
bw.write("hello");
bw.flush();
读出文件
BufferedReader br = new BufferedReader(new FileReader("src//data.txt"));
br.readLine();//读一行
br.read();//读一个ASCII码
直接读
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println(br.readLine());//会比Scanner快不少
直接写
在写的时候尽量先用StringBuilder进行处理,再使用IO流一次性将内容写入,可以节约时间
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write("hello");
bw.flush();
借助Scanner
文件读
Scanner scan = new Scanner(new FileInputStream("src//data.txt"));
System.out.println(scan.nextLine());
直接读
Scanner scan = new Scanner(System.in);
DFS
蓝桥杯常用的搜索算法
常用在填空题目和简单的大题,由于递归调试的不便,要注意手动设置几组易于分析的数据,不要随便一出结果就往上填
动态规划很多时候就是在DFS基础上加一个备忘录(memo)数组
模板:
dfs(int depth,int value,...等一些其他条件){
//设置出口
if(出口条件){
//进行一下处理
return;
}
//进行状态转移
for(int i = 0;i<图的长度等边界条件;i++){
//通常会设置一个标记数组来辅助dfs算法进行递归
marked[i] = true;
dfs(depth+1,value+计算后的值,...等)
//将标记数组还原
marked[i] = fasle;
}
}
例题
问题描述
作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员,组成球队的首发阵容。
每位球员担任 1 号位至 5 号位时的评分如下表所示。请你计算首发阵容 1号位至 5 号位的评分之和最大可能是多少?
1 97 90 0 0 0
2 92 85 96 0 0
3 0 0 0 0 93
4 0 0 0 80 86
5 89 83 97 0 0
6 82 86 0 0 0
7 0 0 0 87 90
8 0 97 96 0 0
9 0 0 89 0 0
10 95 99 0 0 0
11 0 0 96 97 0
12 0 0 0 93 98
13 94 91 0 0 0
14 0 83 87 0 0
15 0 0 98 97 98
16 0 0 0 93 86
17 98 83 99 98 81
18 93 87 92 96 98
19 0 0 0 89 92
20 0 99 96 95 81
(如果你把以上文字复制到文本文件中,请务必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 team.txt,内容与上面表格中的相同,请注意第一列是编号)
public class Main {
public static int MAX = -1;
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(new FileInputStream("src//data.txt"));
int[][] nums =new int[20][6];
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 6; j++) {
nums[i][j] = scan.nextInt();
}
}
dfs(nums,1,0,new boolean[20]);
System.out.println(MAX);
}
private static void dfs(int[][] nums, int depth,int sum,boolean[]dic) {
//设置出口
if(depth==6) {
if(sum>MAX) {
MAX = sum;
}
return;
}
//递归处理
for (int i = 0; i < 20; i++) {
if(dic[i]) continue;
int val = nums[i][depth];
dic[i] = true;
dfs(nums,depth+1,sum+val,dic);
dic[i] = false;
}
}
}
其他常用算法
素数
static boolean isPrim(int n) {
if(n==1)
return false;
for(int i=2;i*i<=Math.sqrt(n);i++)
if(n%i==0)
return false;
return true;
}
//倍筛法
boolean[] is = new boolean[1000005];
is[1] = true;//true表示不是素数
for(int i=2;i<1000005;i++)
if(!is[2])
for(int j=2*i;j<1000005;j+=i)
is[j] = true;
System.out.println(is[2004]);
最大公约数gcd
public static int gcd(int a,int b) {
return b==0?a:gcd(b,a%b);
}
最小公倍数lcm
public static int lcm(int a,int b) {
return a*b/gcd(a,b);
}
多个数共同的gcd和lcm模板
public static int gcd(int[] a) {
int n = a.length;
int g = a[0];
for(int i=1;i<n;i++)
g = gcd(g,a[i]);
return g;
}
public static int lcm(int[] a) {
int n = a.length;
int l = a[0];
for(int i=1;i<n;i++)
l = lcm(l,a[i]);
return l;
}
求模
(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p ) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
a ^ b % p = ((a % p)^b) % p (4)
常用API:
进制转换
十进制转换成其他进制:
10进制转2进制 Integer.toBinaryString(n); 一个二进制字符串.
10进制转8进制 Integer.toOctalString(n); 一个八进制字符串
10进制转16进制 Integer.toHexString(n); 一个16进制字符串
10进制转 r 进制 Integer.toString(100, 16); 一个r进制字符串
其他进制转十进制:
Integer.valueOf("FFFF",进制数).toString() ;//返回十进制数