比较菜,笔试四道题一道都没有Ac.
1. 90%
2. 0%
3. 50%
4. 0% 刚刚把这道题磕出来了
第一题一直是90%,好像是哪里的边界不太对。把自己代码发出来给大家分享一下。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @Description: * @Create 2020-08-02 19:02 * @Email: */ public class Main{ public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; while ((s = br.readLine()) != null) { String[] s1 = s.split(" "); int K = Integer.valueOf(s1[0]); int N = Integer.valueOf(s1[1]); int[] arr = new int[N]; s1 = br.readLine().split(" "); for (int i = 0; i < N; i++) { arr[i] = Integer.valueOf(s1[i]); } String res = function1(K, N, arr); System.out.println(res); } br.close(); } private static String function1(int k, int n, int[] arr) { int now = 0; int count = 0; boolean isRight = true; for (int i = 0; i < n; i++) { if (i == n - 1 && now == k) { return "paradox"; } // 每次开始都是往右走 isRight = true; for (int j = 0; j < arr[i]; j++) { if (now == k) { // 换方向 isRight = false; count++; } if (now == 0) { // 换方向 isRight = true; } if (isRight) { now++; } else { now--; } } } int dis = k - now; return dis + " " + count; } }
第二题没有写,自己太菜看不太懂,第三题食堂营养餐的那个题,我暴力过了50%,想不到好的思路,不知道有没有大佬分享一下代码。
import java.awt.event.MouseAdapter; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * @Description: * @Create 2020-08-02 19:57 * @Email: */ public class Main{ public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; while ((s = br.readLine()) != null) { String[] s1 = s.split(" "); int N = Integer.valueOf(s1[0]); int M = Integer.valueOf(s1[1]); int T = Integer.valueOf(s1[2]); int[][] lunch = new int[N][2]; int[][] dinner = new int[M][2]; int max = Integer.MIN_VALUE; // 中餐最大营养值 int max2 = Integer.MIN_VALUE; // 晚餐最大营养值 for (int i = 0; i < N; i++) { s1 = br.readLine().split(" "); lunch[i][0] = Integer.valueOf(s1[0]); lunch[i][1] = Integer.valueOf(s1[1]); max = Math.max(max, lunch[i][1]); } for (int i = 0; i < M; i++) { s1 = br.readLine().split(" "); dinner[i][0] = Integer.valueOf(s1[0]); dinner[i][1] = Integer.valueOf(s1[1]); max2 = Math.max(max2, dinner[i][1]); } if (max + max2 < T) { System.out.println(-1); continue; } int res = function(lunch, dinner, T); System.out.println(res); } br.close(); } private static int function(int[][] lunch, int[][] dinner, int t) { if (t == 0) return 0; int n = lunch.length; int m = dinner.length; int dis = Integer.MAX_VALUE; for (int i = 0; i < n; i++) { if (lunch[i][1] >= t) { dis = Math.min(dis, lunch[i][0]); } for (int j = 0; j < m; j++) { if (lunch[i][1] + dinner[j][1] >= t) { dis = Math.min(dis, lunch[i][0] + dinner[j][0]); } } } for (int j = 0; j < m; j++) { if (dinner[j][1] >= t) { dis = Math.min(dis, dinner[j][0]); } } if (dis != Integer.MAX_VALUE) return dis; return -1; } }
第四题,就是种菜问题,能种的地方用'#'表示,每个地方中的菜不能和周围四个方向的菜相同,总共有6中菜可供选择,大概是这个意思,求出6*6矩阵中总共可能的次数
考完后磕了半天做出来了,题目用例都是对的,分享一下,不知道有没有人分享一下优化思路。
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /* 用例1 ##**** ##**** ****** ****** ****** ****** * 630 1000000009 * * * */ /* 用例2 #***** ****** ****** ****** ****** *****# * 36 */ /** * @Description: * @Create 2020-08-02 20:16 * @Email: */ public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = null; char[][] matrix = new char[6][6]; while ((s = br.readLine()) != null) { matrix[0] = s.toCharArray(); for (int i = 0; i < 5; i++) { matrix[i + 1] = br.readLine().toCharArray(); } int res = function(matrix); System.out.println(res); } br.close(); } static int[][] dd = new int[36][6]; static int res = 0; static int Num = 0; private static int function(char[][] matrix) { res = 0; int num = 0; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (matrix[i][j] == '#') { num++; } } } Num = num; backTrack(matrix, 0, 0, 0); return res; } private static void backTrack(char[][] matrix, int count, int row, int col) { if (count == Num) { res++; res %= 1000000009; return; } int before = row*6 + col; for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if (i * 6 + j < before) { // 保证往后遍历 避免重复 continue; } if (matrix[i][j] == '#') { int index = i * 6 + j; for (int t = 0; t < 6; t++) { if (check(i, j, t)) {// 如果能放 matrix[i][j] = '*'; // 打个标记 dd[index][t] = 1; // 记录这个位置中的植物 backTrack(matrix, count + 1, i, j); dd[index][t] = 0; // 撤销 matrix[i][j] = '#'; // 撤销 } } } } } return; } // 周围四个方向 static int[][] dir = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; /** * 检查周围 看看当前位置能不能中这类植物 * * @param row * @param col * @param kind * @return */ private static boolean check(int row, int col, int kind) { for (int[] arr : dir) { int x = row + arr[0]; int y = col + arr[1]; if (x >= 0 && x < 6 && y >= 0 && y < 6) { int index = x * 6 + y; if (dd[index][kind] == 1) return false; } } return true; } }
第四题,添加一个非回溯算法,回溯确实很花时间,大家感兴趣可以看看这个算法。加了点注释,代码我测了,和回溯结果一样的
结果没问题。感兴趣可以自己可以测一下,可能有的逻辑想的不太好,所以代码写的很繁琐。
/** * 一个一个往后检测 * * @param matrix * @return */ private static int dpFunction(char[][] matrix) { int[][] dp = new int[6][6]; boolean flag = false; int pre = 0; // 保存前一个点可能的数 for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { pre %= 1000000009; if (matrix[i][j] == '*') { //如果不能种直接跟随前一个状态 dp[i][j] = pre; continue; } else { if (!flag) {//保证这里代码只执行一次 dp[i][j] = 6; pre = 6; flag = true; } else { // 如果能种并且在第一列时 if (j == 0) { // 如果还在第一行 if (i == 0) { dp[i][j] = pre * 5; pre = dp[i][j]; continue; } // 如果不在第一行 /* ** * * # */ if (matrix[i - 1][j] == '*') { dp[i][j] = pre * 6; pre = dp[i][j]; } else { dp[i][j] = pre * 5; pre = dp[i][j]; } } else { // 如果能种 且不在第一列的情况 // 如果还在第一行 if (i == 0) { if (matrix[i][j - 1] == '#') { dp[i][j] = pre * 5; } else { dp[i][j] = pre * 6; } pre = dp[i][j]; continue; } // 然后四种情况讨论 if (matrix[i][j - 1] == '*' && matrix[i - 1][j] == '*') { dp[i][j] = pre * 6; pre = dp[i][j]; continue; } if (matrix[i][j - 1] == '*' && matrix[i - 1][j] == '#') { dp[i][j] = pre * 5; pre = dp[i][j]; continue; } if (matrix[i][j - 1] == '#' && matrix[i - 1][j] == '*') { dp[i][j] = pre * 5; pre = dp[i][j]; continue; } // 主要是这一种的判断 /* * **# * *## * * 当左边和上边相同的菜时 要乘以5 * 不同时乘以4 根据前一个状态写出下边递推方程 */ if (matrix[i][j - 1] == '#' && matrix[i - 1][j] == '#') { dp[i][j] = pre * 4 + dp[i - 1][j]; pre = dp[i][j]; continue; } } } } } } return pre % 1000000009; }
全部评论
(6) 回帖