笔试
2021-6-16
一共是3道编程题,考得还算比较基础吧,就是华为的编辑器用着不太舒服,快捷键也都不能用,涉及到输入输出的时候也比较麻烦,总的来说对Java不是很友好,思路一下子出来了,代码和调试搞了半天。看有些大牛已经写了博客,我借用一下他们的题目描述,然后写一下分析吧。代码我就不敲了(想想还是敲一下吧,不然真看不懂改了)。
思路:
直接想到的是用树做,然后把路径遍历出来。写着写着发现其实可以不用树来做。每一行给出的两个节点,左边的节点可能作为根节点,而右边的节点肯定不会是根节点。所以用一个Set记录左边的节点,每一次查看右边的节点,如果右边的节点在set中出现过,就从set中去除。然后我们还要用一个Map<String,Node>来记录已经出现过的Node,防止重新创建。Node中用一个next来连接上一个节点。
处理之后,set中存储的就都是根节点了。遍历set中的接待,对于每一个寻找next,知道next的值跟最后给出的根域名相同,则将这一串放入List ans中,最后对ans排序并输出。
结果:
AC 75% 不知道是哪里错了,有看到的大佬指点一下。(我大概知道错误了,每次读取一行的时候,把右边的节点从set中删除,但是可能这个节点之后又出现在左边并又放到了set中,需要用一个临时List存储一下右边Node,最后一起删除)
AC 75 的版本
package 华为;
import java.util.*;
public class HuaWei1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
List<String> ans = new ArrayList<>(); // 记录结果
Map<String, Node> map = new HashMap<>(); // 记录已经出现过的Node
Set<Node> set = new HashSet<>(); // 记录根节点
for (int i = 0; i < n; i++) {
String s = scanner.nextLine();
String[] ss = s.split(" ");
Node pre,next;
if(!map.containsKey(ss[0])){
pre = new Node(ss[0]);
map.put(ss[0],pre);
set.add(pre);
}else{
pre = map.get(ss[0]);
}
if(!map.containsKey(ss[1])){
next = new Node(ss[1]);
map.put(ss[1],next);
}else{
next = map.get(ss[1]);
}
set.remove(next);
pre.next = next;
}
String compare = scanner.nextLine();
set.forEach(s->{
StringBuilder sb = new StringBuilder("");
boolean flag = false; // 表示这一次遍历到最后是不是我们所要的根据域名
while (s!=null){
if(!s.value.equals(compare)){
sb.append(s.value);
sb.append(".");
}else{
sb.append(compare);
flag = true;
break;
}
s = s.next;
}
if(flag){
ans.add(sb.toString());
}
});
ans.sort(String::compareTo);
ans.forEach(System.out::println);
}
}
class Node{
public String value;
public Node next; // 指向父节点
public Node(String value){
this.value = value;
}
}
修改后的版本,应该能全AC
package 华为;
import java.util.*;
public class HuaWei1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
List<String> ans = new ArrayList<>();
Map<String, Node> map = new HashMap<>();
Set<Node> set = new HashSet<>();
Set<Node> right = new HashSet<>();
for (int i = 0; i < n; i++) {
String s = scanner.nextLine();
String[] ss = s.split(" ");
Node pre,next;
if(!map.containsKey(ss[0])){
pre = new Node(ss[0]);
map.put(ss[0],pre);
set.add(pre);
}else{
pre = map.get(ss[0]);
}
if(!map.containsKey(ss[1])){
next = new Node(ss[1]);
map.put(ss[1],next);
right.add(next);
}else{
next = map.get(ss[1]);
}
pre.next = next;
}
set.removeIf(right::contains); // 函数式变成,过滤器函数, 传参1 return boolean
String compare = scanner.nextLine();
set.forEach(s->{
StringBuilder sb = new StringBuilder("");
boolean flag = false; // 表示这一次遍历到最后是不是我们所要的根据域名
while (s!=null){
if(!s.value.equals(compare)){
sb.append(s.value);
sb.append(".");
}else{
sb.append(compare);
flag = true;
break;
}
s = s.next;
}
if(flag){
ans.add(sb.toString());
}
});
ans.sort(String::compareTo);
ans.forEach(System.out::println);
}
}
class Node{
public String value;
public Node next;
public Node(String value){
this.value = value;
}
}
思路:
就是求一个多插树的最长路径和
AC了65%,不知道问题在哪里
package 华为;
import java.util.Scanner;
public class HuaWei2 {
private static int max = 1<<31;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
int[] value = new int[n];
int[][] children = new int[n][100];
for (int i = 0; i < n; i++) {
String s = scanner.nextLine();
String[] ss = s.split("\\s+");// 这里可能两个数之间的空格不止一个,所以用正则
value[i] = Integer.parseInt(ss[1]);
for (int j = 2; j < ss.length; j++) {
children[i][j-2] = Integer.parseInt(ss[j]);
}
}
dfs(value,children,value[0],0);
System.out.println(max);
}
private static void dfs(int[] value, int[][] children, int currentCost, int index) {
if(children[index][0]==0){
max = Math.max(max,currentCost);
}else{
int i =0;
while (children[index][i]>0){
int nextIndex = children[index][i++];
dfs(value,children,currentCost+value[nextIndex],nextIndex);
}
}
}
}
简单的回溯算法。AC 70%
package 华为;
import java.util.Scanner;
public class Huawei3 {
private static int cnt;
private static final int SIZE = 20;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[][] nums = new int[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
nums[i][j] = scanner.nextInt();
}
}
int maxWhite = 0;
int maxBlack = 0;
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
if (nums[i][j] == 1) {
cnt = 0;
//白子
traceBack(i, j, 1, nums);
maxWhite = Math.max(maxWhite, cnt);
}
if (nums[i][j] == 2) {
cnt = 0;
//黑子
traceBack(i, j, 2, nums);
maxBlack = Math.max(maxBlack, cnt);
}
}
}
System.out.println(maxWhite);
System.out.println(maxBlack);
if (maxWhite > maxBlack) {
System.out.println("white");
} else if (maxBlack == maxWhite) {
System.out.println("equal");
} else {
System.out.println("black");
}
}
private static void traceBack(int i, int j, int target, int[][] nums) {
if (i < 0 || i >= SIZE) return;
if (j < 0 || j >= SIZE) return;
if (nums[i][j] == target) {
cnt++;
nums[i][j] = 0;
traceBack(i + 1, j, target, nums);
traceBack(i - 1, j, target, nums);
traceBack(i, j - 1, target, nums);
traceBack(i, j + 1, target, nums);
}
}
}
测评
2021-06-18 12:00
一共36题,做起来比较复杂,会出现重复的选项,好像是七级量表。忘记截图了…
鸣谢
https://blog.youkuaiyun.com/Huntermanwp/article/details/117981494