校招编程真题总结
输入模板
比Scanner快不少,具体原理需要看一下。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { //注意 public static void main (String[] args) throws IOException{ BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(bf.readLine()); } }
动态规划-01背包问题
每个货物都可以无限使用,但是要求背包必须装满,而且要求背包中的物品数目最少。
由于货物是无限的,那么假设dp[n]表示背包容量为n的能够装满的最少货物个数。
如果选择3, 5, 7任意的一种货物重量,那么dp[n-3]、dp[n-5]、dp[n-7]就会是背包容量为n的一种选择,
所以问题就转化为了求dp[n-x],dp[i] = min(min(dp[i-3],dp[i-5]),dp[i-7])+1。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static void main (String[] args) throws IOException{ BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); int n = Integer.parseInt(bf.readLine()); if (n < 8) { if (n == 3 || n == 5 || n == 7) System.out.println(1); else if (n ==6) System.out.println(2); else System.out.println(-1); } else { int[] dp = new int[n+1]; dp[1] = Integer.MAX_VALUE; dp[2] = Integer.MAX_VALUE; dp[4] = Integer.MAX_VALUE; dp[3] = 1; dp[5] = 1; dp[7] = 1; dp[6] = 2; for (int i = 8; i <= n; i++) { int temp = Math.min(dp[i-3], Math.min(dp[i-5], dp[i-7])); if (temp == Integer.MAX_VALUE) dp[i] = Integer.MAX_VALUE; else dp[i] = temp + 1; } if (dp[n] == Integer.MAX_VALUE) System.out.println(-1); else System.out.println(dp[n]); } } }
动态规划-回文字符串
想到回文字符串立马要想到最常用的解题思路:
- 中心扩散法
- 动态规划
- 马拉车算法(?不会)
回文子串
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static void main (String[] args) throws IOException{ BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String str = bf.readLine(); int n = str.length(); int count = n; int[][] dp = new int[n][n]; dp[0][0] = 1; for (int i = 1; i < n; i++) { dp[i][i] = 1; for (int j = i-1; j >= 0; j--) { if (str.charAt(i) == str.charAt(j) && (j+1 > i-1 || dp[j+1][i-1] == 1)) { dp[j][i] = 1; count++; } } } System.out.println(count); } }
动态规划-机器人问题变种
拜访 -美团2016年面试题
(x1,y1),(x2,y2)两点任意指定,需要先进行交换,令x1是左面的点,令x2是右面的点。
int x1 = 0; int y1 = 0; int x2 = 0; int y2 = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (map[i][j] == 1) { x1 = i; y1 = j; } else if (map[i][j] == 2) { x2 = i; y2 = j; } } } if (x1 == x2 && y1 == y2) { return 1; } if (x1 > x2) { int temp = x1; x1 = x2; x2 = temp; temp = y1; y1 = y2; y2 = temp; }
然后在进行按照机器人路径那么写就可以了。
网格走法数目
注意走的是格点不是格子就能做对了。
import java.util.*; import java.math.*; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class Main { public static void main (String[] args) throws IOException{ BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); String[] s = bf.readLine().split(" "); int x = Integer.parseInt(s[0]); int y = Integer.parseInt(s[1]); int[][] dp = new int[x+1][y+1]; dp[0][0] = 1; for (int i = 1; i <= x; i++) { dp[i][0] = 1; } for (int i = 1; i <= y; i++) { dp[0][i] = 1; } for (int i = 1; i <= x; i++) { for (int j = 1; j <= y; j++) { dp[i][j] = dp[i-1][j] + dp[i][j-1]; } } System.out.println(dp[x][y]); } }
图
创建图
static ArrayList<Integer>[] graph; graph = new ArrayList[n+1]; graph = new ArrayList[n+1]; for (int i = 0; i <= n; i++) { graph[i] = new ArrayList<>(); } for (int i = 0; i < m; i++) { s = bf.readLine().split(" "); int u = Integer.parseInt(s[0]); int v = Integer.parseInt(s[1]); graph[u].add(v); graph[v].add(u); }
bfs
private static int bfs(int x, int n, int m) { int[] dist = new int[n + m + 1]; LinkedList<Integer> queue = new LinkedList<>(); dist[x] = 1; queue.offer(x); while (!queue.isEmpty()) { int cur = queue.poll(); for (Integer e : graph[cur]) { if (dist[e] == 0) { dist[e] = dist[cur] + 1; queue.offer(e); } } } return dist[n]; }