蓝桥杯笔记:
阶乘计算
N! 后面恰好有几个0,就拿N一直除以5知道N<0,然后得到的值加一起,
例如:后面有两个0 就是
10/5=2 2/5=0 2+0=2 so 10! 后面有两个0
40/5=8 8/5=1 8+1=9 so 40! 后面有九个0
int 2* 32 >10*9
long 2* 64>10*18
eclipse 代码补全 alt + /
求最大公约数以及最小公倍数
public class LCM {
// 计算最大公约数的方法
public static int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
// 计算最小公倍数的方法
public static int lcm(int a, int b) {
return (a * b) / gcd(a, b);
}
public static void main(String[] args) {
int a = 12;
int b = 15;
int lcmResult = lcm(a, b);
}
}
BFS算法框架
// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
Queue<Node> q; // 核心数据结构
Set<Node> visited; // 避免走回头路
q.offer(start); // 将起点加入队列
visited.add(start);
while (q not empty) {
int sz = q.size();
/* 将当前队列中的所有节点向四周扩散 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
/* 划重点:这里判断是否到达终点 */
if (cur is target)
return step;
/* 将 cur 的相邻节点加入队列 */
for (Node x : cur.adj()) {
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
}
}
// 如果走到这里,说明在图中没有找到目标节点
}//bfs先找到的一定是最短
dfs/回溯算法框架
回溯算法看labuladong总结组合和排序
result = []
def backtrack(路径, 选择列表):
if 满足结束条件:
result.add(路径)
return
for 选择 in 选择列表:
做选择
backtrack(路径, 选择列表)
撤销选择
动态规划框架
# 自顶向下递归的动态规划
def dp(状态1, 状态2, ...):
for 选择 in 所有可能的选择:
# 此时的状态已经因为做了选择而改变
result = 求最值(result, dp(状态1, 状态2, ...))
return result
# 自底向上迭代的动态规划
# 初始化 base case
dp[0][0][...] = base case
# 进行状态转移
for 状态1 in 状态1的所有取值:
for 状态2 in 状态2的所有取值:
for ...
dp[状态1][状态2][...] = 求最值(选择1,选择2...)
二分搜索框架
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意
while(left <= right) {
int mid = left + (right - left) / 2;
if(nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1; // 注意
else if (nums[mid] > target)
right = mid - 1; // 注意
}
return -1;
}
前缀和
一维数组前缀和
class NumArray {
// 前缀和数组
private int[] preSum;
/* 输入一个数组,构造前缀和 */
public NumArray(int[] nums) {
// preSum[0] = 0,便于计算累加和
preSum = new int[nums.length + 1];
// 计算 nums 的累加和
for (int i = 1; i < preSum.length; i++) {
preSum[i] = preSum[i - 1] + nums[i - 1];
}
}
/* 查询闭区间 [left, right] 的累加和 */
public int sumRange(int left, int right) {
return preSum[right + 1] - preSum[left];
}
}
二维数组前缀和
class NumMatrix {
// 定义:preSum[i][j] 记录 matrix 中子矩阵 [0, 0, i-1, j-1] 的元素和
private int[][] preSum;
public NumMatrix(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
if (m == 0 || n == 0) return;
// 构造前缀和矩阵
preSum = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
// 计算每个矩阵 [0, 0, i, j] 的元素和
preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i - 1][j - 1] - preSum[i-1][j-1];
}
}
}
// 计算子矩阵 [x1, y1, x2, y2] 的元素和
public int sumRegion(int x1, int y1, int x2, int y2) {
// 目标矩阵之和由四个相邻矩阵运算获得
return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
}
}
图论最短路径
Floyd算法模板
用于查找图中所有顶点对之间的最短路径的动态规划算法,
时间复杂度是 O(V^3),其中 V 是顶点的数量。
public class FloydWarshall {
private static final int INF = 99999, V = 4; // INF 表示无穷大,V 是顶点的数量
void floydWarshall(int graph[][]) {
int dist[][] = new int[V][V];
int i, j, k;
// 初始化距离矩阵为输入图矩阵
for (i = 0; i < V; i++)
for (j = 0; j < V; j++)
dist[i][j] = graph[i][j];
// 对所有顶点对 (i, j),检查是否存在一个顶点 k 使得从 i 到 k 再到 j 的路径比已知的路径更短
for (k = 0; k < V; k++) {
for (i = 0; i < V; i++) {
for (j = 0; j < V; j++) {
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
// 打印最短距离矩阵
printSolution(dist);
}
void printSolution(int dist[][]) {
System.out.println("Following matrix shows the shortest distances between every pair of vertices");
for (int i = 0; i < V; ++i) {
for (int j = 0; j < V; ++j) {
if (dist[i][j] == INF)
System.out.print("INF ");
else
System.out.print(dist[i][j] + " ");
}
System.out.println();
}
}
public static void main(String args[]) {
// 测试图
int graph[][] = { { 0, 5, INF, 10 },
{ INF, 0, 3, INF },
{ INF, INF, 0, 1 },
{ INF, INF, INF, 0 } };
FloydWarshall a = new FloydWarshall();
// 执行算法
a.floydWarshall(graph);
}
}
快速幂算法模版
public class FastPower {
public static long fastPower(long base, long exponent, long modulus) {
long result = 1;
base = base % modulus;
while (exponent > 0) {
// 如果指数为奇数,则累乘底数
if ((exponent & 1) == 1) {
result = (result * base) % modulus;
}
// 底数平方
base = (base * base) % modulus;
// 指数右移一位,相当于除以2
exponent >>= 1;
}
return result;
}
public static void main(String[] args) {
long base = 2;
long exponent = 10;
long modulus = 1000000007; // 取模的值,如果需要计算的是普通的幂运算,可以将modulus设为1
long result = fastPower(base, exponent, modulus);
System.out.println(base + " 的 " + exponent + " 次方模 " + modulus + " 的结果是 " + result);
}
}
快读模版
StreamTokenizer streamTokenizer; //读取数字
BufferedReader bufferedReader; //读取字符串
public FastRead() {
streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
br = new BufferedReader(new InputStreamReader(System.in));
}
int gtInt() throws IOException {
streamTokenizer.nextToken();
int x = (int) streamTokenizer.nval;
return x;
}
long gtLong() throws IOException {
streamTokenizer.nextToken();
long l = (long) streamTokenizer.nval;
return l;
}
double gtDouble() throws IOException {
streamTokenizer.nextToken();
double x = streamTokenizer.nval;
return x;
}
String gtString() throws IOException {
String s = bufferedReader.readLine();
return s;
}
}