快手笔试题
1. 蓄水池问题
默认输入 较小的为父水池,较大的为子水池
import java.util.*; /** * @author zzm * @data 2020/4/20 23:23 * 在你面前有n个蓄水池,他们组成了树形结构(由n-1条边连接)。蓄水池节点编号从1开始到n。 * 对每个蓄水池节点来说,他的儿子蓄水池节点都摆放在他的下面,并且和它用水管相连,根据重力,水会向下流动。现在我们要在蓄水池上做一些操作: * 1. 把节点v填满水。然后v的所有儿子节点水也会被填满 * 2. 清空节点v的水。然后v所有的父亲节点水都会被清空 * 3. 询问每个蓄水池节点是否有水。 * 初始状态时候,每个节点都是空的。 * 现在我们会依次进行一系列操作,我们想提前知道每次操作后的结果,你能帮忙解决吗? * 输入描述: * 第一行包含一个正整数n(1<=n<=1000),表示蓄水池节点的数量。 * 后面n-1行,每行有两个数字a[i], b[i]。(1<=a[i], b[i]<= n, a[i]!=b[i])表示蓄水池的连接关系。 * 接下来的一行包含一个整数q(1<=q<=1000),表示我们要进行的操作的数量。 * 最后的q行中,每行包含两个数字c[i] (1<=c[i]<=3)和v[i](1<=v[i]<=n)。其中c[i]表示操作类型(1,2或者3)。v[i]表示操作对应的蓄水池节点。 * 输入数据保证合理,是一个连通的树。 * 输出描述: * 对于每个操作3(c[i] == 3),输出一个数字1或者0。1表示v[i]蓄水池节点有水,0表示没水。 */ public class KSwaterPool { static tree[] trees; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); trees = new tree[n+1]; for (int i = 1; i <= n; i++) trees[i] = new tree(); for (int i = 0; i < n - 1; i++) { int f = scanner.nextInt(), c = scanner.nextInt(); if(f>c){ int temp = f; f=c; c=temp; } trees[f].chile.add(c); trees[c].father.add(f); } int len = scanner.nextInt(); for (int i = 0; i < len; i++) { int op = scanner.nextInt(), aim = scanner.nextInt(); //灌满 if (op == 1) full(aim); else if (op == 2) poll(aim); else System.out.println(trees[aim].hasWater ? 1 : 0); } } private static void full(int t) { tree tree = trees[t]; if (!tree.hasWater) { tree.hasWater = true; for (int a : tree.chile) full(a); } } private static void poll(int t) { tree tree = trees[t]; if (tree.hasWater) { tree.hasWater = false; for (int a : tree.father) poll(a); } } } class tree { List<Integer> father; List<Integer> chile; boolean hasWater; tree() { this.father = new ArrayList<>(); this.chile = new ArrayList<>(); hasWater = false; } }
2. 全班最大考试成绩
暴力法找每道题目最多的答案
import java.util.*; /** * @author zzm * @data 2020/4/20 22:37 * 现在你的班级刚刚参加了一个只有单选题的考试。班级一共n个学生,考试有m个问题。每个题目都有5个可选答案(A,B,C,D,E)。 * 并且每个题目只有一个正确答案。每个题目的分数并不一样,第i个题目的分数用a[i]表示。如果题目没答对该题会获得0分。 * 考试结束后,每个学生都记得自己的答案,但是他们还不知道正确答案是什么。如果非常乐观的考虑,他们班级最多可能得到多少分呢? * 输入描述: * 第一行包含2个正整数,n和m。(1 <= n, m <= 1000,n是班级中学生数量,m是题目的数量) * 下面n行数据每行包含一个string si,表示第i个学生的答案。si的第j个字符表示该学生第j个题目的答案。 * 输出描述: * 一个正整数,全班学生最大的可能获得的分数总和。 * 输入例子1: * 2 4 * ABCD * ABCE * 1 2 3 4 * 输出例子1: * 16 */ public class KSexam { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String[] mn = scanner.nextLine().split(" "); int n = Integer.parseInt(mn[0]); int m = Integer.parseInt(mn[1]); if (n <= 0 || m <= 0) { System.out.println(0); return; } char[][] answers = new char[n][m]; int[] core = new int[m]; for (int i = 0; i < n; i++) answers[i] = scanner.nextLine().toCharArray(); String[] split = scanner.nextLine().split(" "); for (int i = 0; i < m; i++) core[i] = Integer.parseInt(split[i]); scanner.close(); int res = 0; for (int i = 0; i < m; i++) { int[] temp = new int[5]; int maxIndex = 0; for (int j = 0; j < n; j++) temp[answers[j][i] - 'A']++; for (int j = 0; j < 5; j++) if (temp[j] > temp[maxIndex]) maxIndex = j; res += core[i] * temp[maxIndex]; } System.out.println(res); } }
3. 将数组分成两部分 使得 两部分和的差的绝对值最小
import java.util.*; /** * @author zzm * @data 2020/5/22 8:29 * 给定一个数组,每个元素范围是0~K(K < 整数最大值2^32),将该数组分成两部分,使得 |S1- S2|最小,其中S1和S2分别是数组两部分的元素之和。 */ public class Main { static int min = Integer.MAX_VALUE; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int[] nums = new int[n]; int sum = 0; for (int i = 0; i < n; i++) { nums[i] = scanner.nextInt(); sum += nums[i]; } scanner.close(); helper(nums,sum,0,0); System.out.println(min); } private static void helper(int[] nums, int sum, int tempSum, int index) { if (index == nums.length) { min = Math.min(min, Math.abs(sum - 2 * tempSum)); return; } helper(nums, sum, tempSum + nums[index], index + 1); helper(nums, sum, tempSum, index + 1); } }
4. 最长等差数列
思路:
HashMap<Integer, Integer>[] maps = new HashMap[n]; maps 记录当前位置数为结尾的 所有等差数列的最大长度
注意: Arrays.fill(maps, new HashMap<>()) 会给数组填充同一个 map!!
import java.util.*; /** * @author zzm * @data 2020/5/22 9:03 * 给定一个未排序数组,找出其中最长的等差数列(无需保证数字顺序)。 */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); if (n <= 2) { System.out.println(n); return; } int[] nums = new int[n]; for (int i = 0; i < n; i++) nums[i] = scanner.nextInt(); scanner.close(); Arrays.sort(nums); int max = 2; HashMap<Integer, Integer>[] maps = new HashMap[n]; for (int j = 0; j < n; j++) { maps[j] = new HashMap<>(); for (int i = 0; i < j; i++) { int dif = nums[j] - nums[i]; Integer len = maps[i].getOrDefault(dif, 1); max = Math.max(max,len+1); maps[j].put(dif,len+1); } } System.out.println(max); } }
5. 判断IPV4 和IPV6
编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址
IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1;
同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。
IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如, 2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。
然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。
同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。
说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。
import java.util.*; /** * @author zzm * @data 2020/5/22 11:29 */ public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); scanner.close(); for (int k = 0; k < 1; k++) { if (s.contains(".")) { String[] split = s.split("\\."); // System.out.println(split.length); if (split.length != 4) break; int i = 0; for (; i < 4; i++) { String str = split[i]; if (str.equals("0") || (!str.startsWith("0"))) { int n = Integer.parseInt(str); if (0 <= n && 255 >= n) continue; break; }else break; } if (i == 4) { System.out.println("IPv4"); return; } } else if (s.contains(":")) { String[] split = s.split(":"); if (split.length != 8) break; int i = 0; for (; i < 8; i++) { String str = split[i]; if(str.equals("0000") || str.equals("000") || str.equals("00")) break; } if(i==8){ System.out.println("IPv6"); return; } } } System.out.println("Neither"); } }

浙公网安备 33010602011771号