华为2022.9.21笔试题目
第二题参考代码:就是 dfs,分为小兵 和 马状态 两种情况下,进行 dfs就可以了,复杂的O(mn)
package com.example.huawei._9_21;
public class _2_anser {
public static void main(String[] args) {
char[][] map = new char[9][];
map[0] = new char[]{'.','.','.','.','.','.','.','.','.'};
map[1] = new char[]{'.','.','.','.','.','X','X','X','.'};
map[2] = new char[]{'.','.','.','.','.','X','.','X','.'};
map[3] = new char[]{'.','.','.','.','.','X','.','X','.'};
map[4] = new char[]{'.','.','.','.','.','X','.','X','S'};
map[5] = new char[]{'X','X','X','X','X','X','.','X','X'};
map[6] = new char[]{'.','.','.','.','.','.','.','.','.'};
map[7] = new char[]{'.','.','.','.','.','.','.','.','.'};
map[8] = new char[]{'.','.','.','.','.','.','.','.','.'};
System.out.println(getCount(map));
char[][] map2 = new char[3][];
map2[0] = new char[]{'S','.'};
map2[1] = new char[]{'.','.'};
map2[2] = new char[]{'.','.'};
System.out.println(getCount(map2));
}
public static int getCount(char[][] map){
int m = map.length;
int n = map[0].length;
int[][] timeBin = new int[m][n];
int[][] timeMa = new int[m][n];
for(int i = 0 ;i < m ;i ++){
for(int j = 0 ; j < n;j ++){
timeBin[i][j] = Integer.MAX_VALUE;
timeMa[i][j] = Integer.MAX_VALUE;
}
}
dfsBin(map,timeBin,timeMa,0,0,0);
if(timeBin[m - 1][n - 1] == Integer.MAX_VALUE && timeMa[m - 1][n - 1] == Integer.MAX_VALUE){
return -1;
}
return Math.min(timeMa[m- 1][n-1],timeBin[m- 1][n-1]);
}
public static void dfsBin(char[][] map,int[][] timeBin,int[][] timeMa,int x, int y,int cost){
if( x < 0 || x >= map[0].length || y < 0 || y >= map.length ){
return;
}
if( map[y][x] == 'X'||timeBin[y][x] <= cost){
return;
}
timeBin[y][x] = cost;
cost++;
if(map[y][x] == 'S'){
dfsMa(map,timeBin,timeMa,x,y,cost);
}
dfsBin(map,timeBin,timeMa,x + 1,y,cost);
dfsBin(map,timeBin,timeMa,x - 1,y,cost);
dfsBin(map,timeBin,timeMa,x,y - 1,cost);
dfsBin(map,timeBin,timeMa,x,y + 1,cost);
}
public static void dfsMa(char[][] map,int[][] timeBin,int[][] timeMa,int x, int y,int cost){
if( x < 0 || x >= map[0].length || y < 0 || y >= map.length ){
return;
}
if( map[y][x] == 'X'||timeMa[y][x] <= cost){
return;
}
timeMa[y][x] = cost;
cost++;
if(map[y][x] == 'S'){
dfsBin(map,timeBin,timeMa,x,y,cost);
}
dfsMa(map,timeBin,timeMa, x + 1,y - 2,cost);
dfsMa(map,timeBin,timeMa, x - 1,y - 2,cost);
dfsMa(map,timeBin,timeMa, x - 1,y + 2,cost);
dfsMa(map,timeBin,timeMa, x + 1,y + 2,cost);
dfsMa(map,timeBin,timeMa, x + 2,y + 1,cost);
dfsMa(map,timeBin,timeMa, x + 2,y - 1,cost);
dfsMa(map,timeBin,timeMa, x - 2,y + 1,cost);
dfsMa(map,timeBin,timeMa, x - 2,y - 1,cost);
}
}
第三题:看起来很复杂,其实很简单,就 dp,也是要分情况,就是某一个树种还是不种,
dp[i][0]表示,在种了第i棵树后,但是后续的树还没有种的情况下所能取到的最大价值
dp[i][1]表示,不种了第i棵树后,但是后续的树还没有种的情况下所能取到的最大价值
首先树得按照树的右边界进行排序
状态方程:
1.dp[i][1] = Max(dp[i-1][0],dp[i-1][1])
2. tempValue =(dp[0][0] - dp[i-1][0])中,边界不会和 i树 冲突的,最大dp值,因为是按照右边界排序,只要 i 不和 j冲突,就意味值 i 不会和 0到j-1的树冲突
dp[i] = val[i] + tempVale
时间复杂度 O(n^2)
package com.example.huawei._9_21;
public class _3_anser {
public static void main(String[] args) {
int n = 4;
int[] pos = new int[]{2,3,4,5};
int[] r= new int[]{1,1,1,2};
int[] val = new int[]{50,10,40,70};
System.out.println(getMaxValue(n,pos,val,r));
n = 5;
pos = new int[]{2,3,6,5,7};
r= new int[]{1,1,3,1,1};
val = new int[]{20,20,100,70,60};
System.out.println(getMaxValue(n,pos,val,r));
}
public static int getMaxValue(int n,int[] pos,int[] val,int[] r){
int res = 0;
int[][] lance = new int[n][3];
for(int i = 0; i < n;i++){
lance[i][0] = pos[i] - r[i];
lance[i][1] = pos[i] + r[i];
lance[i][2] = val[i];
}
Arrays.sort(lance,(a,b)-> a[1] - b[1]);//注意数组是按照右边界进行排序的,只有保证右边界有序,dp方程才成立
int[][] dp = new int[n][2];
dp[0][0] = lance[0][2];//代表种树带来的价值
dp[0][1] = 0;//代表不种树的价值
for(int i = 1; i< n;i++){
int tempValue = 0;
for(int j = 0;j < i;j++){
if(lance[j][1] <= lance[i][0])
tempValue = Math.max(tempValue,dp[j][0]);
}
dp[i][0] = tempValue + lance[i][2]; //加上自己的价值,表示 种了这棵树能达到的最大价值
dp[i][1] = Math.max(dp[i - 1][1],dp[i - 1][0]);//表示不种这棵树的价值
res = Math.max(Math.max(res,dp[i][0]),dp[i][1]);
}
return res;
}
}

查看10道真题和解析