4月15携程实习生笔试

第一题 盖房子

第一次在某个点建红房子“R",之后每次在新房子左边建绿房子"G",右边建红房子“R"。 输入一个n(1≤n≤12),输出过了n个月房子的排列。 要求: 输入非数字打印“N” 输入数字超出限制,打印“O" 样例:

输入1
输出R
输入2
输出GRR
输入3
输出GGRRGRR

题解

由每次的变化,想到构建二叉树,根节点是"R”,左子节点都是“G",右子节点都是"R",最后进行中序遍历得到结果。

class TreeNode{
String val;
TreeNode left;
TreeNode right;
public TreeNode(String val){
this.val = val;
}

}
public class Main0415 {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
for(int i = 0; i < s.length(); i++){
if(!Character.isDigit(s.charAt(i))) {
System.out.print("N");
return;
}
}
int n = Integer.parseInt(s);
if(n < 1 || n > 12) {
System.out.println("O");
return;
}
inOrder(createTree(new TreeNode("R"), n));
}
//由root构建层数为depth的树
public static TreeNode createTree(TreeNode root, int depth){
if(depth == 1) return root;
root.left = new TreeNode("G");
root.right = new TreeNode("R");
createTree(root.left, depth - 1);
createTree(root.right, depth - 1);
return root;
}
//中序遍历打印结果
public static void inOrder(TreeNode root){
if(root == null) return;
inOrder(root.left);
System.out.print(root.val);
inOrder(root.right);
}
}

还可以做更进一步的简化,使用递归实现树的中序遍历

public class Main0415 {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
for(int i = 0; i < s.length(); i++){
if(!Character.isDigit(s.charAt(i))) {
System.out.print("N");
return;
}
}
int n = Integer.parseInt(s);
if(n < 1 || n > 12) {
System.out.println("O");
return;
}
System.out.println(helper(n, new StringBuilder("R")));
}
public static StringBuilder helper(int n, StringBuilder sb){
if(n == 1) return sb;
return helper(n - 1, new StringBuilder("G")).append(sb).append(helper(n - 1, new StringBuilder("R")));
}
}

第二题 包依赖问题

使用正整数表示包,对给定的被修改的包,求出所有受影响的包(去重)所代表数字的和,若无受影响的包则返回-1。直接依赖和间接依赖的包被修改均定义为受影响。 输入说明: 第一行为整数,表示被修改的包。 第二行开始的后续行都是数组,代表数组的第一个元素依赖后续的元素,注意数组元素可能只有1个,代表该包无依赖。 示例:

输入
4
1,2
3,4,5,6
2,3
6,4,2
8,9
10
输出
12
题解

输入的所有数据第一列依赖后几列的元素 在这里插入图片描述 梳理依赖关系,就能得到包之间影响的对应关系 在这里插入图片描述

通过Integer类型的key和ArrayList类型的value值的map就能存储上面的关系。 然后通过队列queue将包及受影响的包入队,并加入set来统计总和。 代码

import java.util.*;
/**
* 4
* 1,2
* 3,4,5,6
* 2,3
* 6,4,2
* 8,9
* 10
* 输出:12
*/
public class Main04152 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
sc.nextLine();
HashMap<Integer, ArrayList<Integer>> map = new HashMap<>();
while (sc.hasNext()){
String[] s = sc.nextLine().split(",");

int[] num = new int[s.length];
for(int i = 0; i < s.length; i++){
num[i] = Integer.parseInt(s[i]);
}
int target = num[0];
for(int i = 1; i < s.length; i++){
//将后面数字作为key,
int key = num[i];
//每个key对应一个list
ArrayList<Integer> al = map.getOrDefault(key, new ArrayList<>());
al.add(target);
map.put(key, al);
}
}
System.out.println(helper(map, n));
}
public static int helper(HashMap<Integer, ArrayList<Integer>> map, int target){
//如果map中没有target的key,返回-1
if(!map.containsKey(target)) return -1;
Queue<Integer> q = new LinkedList<>();//将每个key对应value中的值加入队列
HashSet<Integer> set = new HashSet<>();
q.offer(target);
set.add(target);
while(!q.isEmpty()){
int size = q.size();
for(int i = 0; i < size; i++){
//通过不断弹出cur循环找对应的value
int cur = q.poll();
//如果map中没有对应的,跳过
if(!map.containsKey(cur)) continue;
//相对的value(list)中的值加入set
for(int m : map.get(cur)){
if(set.contains(m)) continue;
q.offer(m);
set.add(m);
}
}
}
int sum = 0;
for(int s : set){
sum += s;
}
//注意去掉最初加入的target
return sum - target;
}
}

测试结果: 在这里插入图片描述

------ 本文结束感谢您的阅读 ------