2019.3.13 华为实习生机试题目
程序员文章站
2022-06-09 11:03:54
...
题目1
题目描述
输入三个符合规范的IP地址,其中前两个是正常的IP地址,第三个是子网掩码,根据子网掩码计算出两个IP地址是否在同一子网。如果是则输出1,否则输出0。然后根据子网掩码计算出第一个IP地址的子网号并输出,即输出第一个IP地址和子网掩码相与后的结果。
- 测试用例1
输入
192.168.1.1
192.168.2.1
255.255.255.0
输出
0 192.168.1.0
- 测试用例2
输入
192.168.1.1
192.168.1.0
255.255.255.0
输出
1 192.168.1.0
AC代码
package com.csk.huawei;
import java.util.Scanner;
/**
192.168.123.1
192.168.2.1
255.255.255.0
*/
public class Main{
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String ip1 = scanner.next();
String ip2 = scanner.next();
String mask = scanner.next();
isSubNet(ip1, ip2, mask);
//两种计算ip1子网号的方法
ip1SubNetMethod1(ip1, mask);
//ip1SubNetMethod2(ip1, mask);
}
}
//根据子网掩码计算ip1的子网号方法1
private static void ip1SubNetMethod1(String ip1, String mask){
long maskLong = getLong(mask.split("\\."));
long n = Long.bitCount(maskLong); //子网掩码中1的个数
long ip1Long = getLong(ip1.split("\\."));
ip1 = new String(Long.toBinaryString(ip1Long));
ip1 = ip1.substring(0, ip1.length() - (32 - (int)n)); //ip1的子网号对应的二进制
StringBuilder sb = new StringBuilder();
sb.append(ip1);
for(int i = 0;i < 32 - n;i++){
sb.append("0");
}
String s = sb.toString();
String[] ss = new String[4];
ss[0] = s.substring(0, s.length() - 24);
ss[1] = s.substring(ss[0].length(), ss[0].length() + 8);
ss[2] = s.substring(ss[0].length() + ss[1].length(), ss[0].length() + ss[1].length() + 8);
ss[3] = s.substring(s.length() - 8, s.length());
System.out.println(Integer.parseInt(ss[0], 2) + "." + Integer.parseInt(ss[1],2) + "." +
Integer.parseInt(ss[2],2) + "." + Integer.parseInt(ss[3]));
}
//根据子网掩码计算ip1的子网号方法2
private static void ip1SubNetMethod2(String ip1, String mask){
long maskLong = getLong(mask.split("\\."));
long ip1Long = getLong(ip1.split("\\."));
Long tmp = maskLong & ip1Long;
String s = Long.toBinaryString(tmp);
String[] ss = new String[4];
ss[0] = s.substring(0, s.length() - 24);
ss[1] = s.substring(ss[0].length(), ss[0].length() + 8);
ss[2] = s.substring(ss[0].length() + ss[1].length(), ss[0].length() + ss[1].length() + 8);
ss[3] = s.substring(s.length() - 8, s.length());
System.out.println(Integer.parseInt(ss[0], 2) + "." + Integer.parseInt(ss[1],2) + "." +
Integer.parseInt(ss[2],2) + "." + Integer.parseInt(ss[3]));
}
//根据子网掩码判断ip1和ip2是否在同一个子网
private static void isSubNet(String ip1, String ip2, String mask){
long maskLong = getLong(mask.split("\\."));
long ip1Long = getLong(ip1.split("\\."));
long ip2Long = getLong(ip2.split("\\."));
long n = Long.bitCount(maskLong); //子网掩码中1的个数
ip1 = new String(Long.toBinaryString(ip1Long));
ip1 = ip1.substring(0, ip1.length() - (32 - (int)n)); //ip1的子网号对应的二进制
ip2 = new String(Long.toBinaryString(ip2Long));
ip2 = ip2.substring(0, ip2.length() - (32 - (int)n)); ////ip2的子网号对应的二进制
if(ip1.equals(ip2)) System.out.print(1 + " "); ////ip1和ip2的子网号相同
else System.out.print(0 + " ");
}
//根据一个IP地址的四部分组合成一个long类型的数字(保存在long中是为了防止int类型溢出。
// 如255.0.0.0转换为二进制后就是11111111000000000000000000000000,
// 在java中最高位是符号位,所以这是一个负数。)
private static long getLong(String[] ss){
long res = 0l;
res += new Long(ss[0]) << 24;
res += new Long(ss[1]) << 16;
res += new Long(ss[2]) << 8;
res += new Long(ss[3]);
return res;
}
}
题目2
有兴趣的同学可以看这里,链接里面是一道leetcode hard难度的题目,华为的第二道机试题在这个的基础上增加了约束。
一个只由数字1和0组成的矩阵,计算此矩阵中所包含正方形的最大面积,满足要求的正方形
必须全由1组成。
输入
第一行输入数字n,代表接下来有n行,
接下来是n行长度相同且只有字符1和0组成的字符串
输出
最大正方形面积。如果存在多个最大面积相同的正方形,则只输出最大正方形的面积。
- 测试用例1
输入
3
110
111
110
输出
4 - 测试用例2
输入
1
10111101111
输出
1
AC代码
package com.csk.huawei;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
int n = scanner.nextInt();
String s = scanner.next();
int m = s.length();
int[][] arrays = new int[n][m];
for(int i = 0;i < m;i++)
arrays[0][i] = s.charAt(i) - '0';
for(int i = 1;i < n;i++){
s = scanner.next();
for(int j = 0;j < m;j++)
arrays[i][j] = s.charAt(j) - '0';
}
int max = 0;
int[] height = new int[m];
for(int[] array : arrays){
for(int i = 0;i < n;i++){
if(array[i] == 1) height[i]++;
else height[i] = 0;
}
max = Math.max(max, helper(height));
}
System.out.println(max);
}
}
private static int helper(int[] height){
return helperCore(height, 0, height.length - 1);
}
private static int helperCore(int[] height, int start, int end){
if(start > end) return 0;
if(start == end) return height[start];
int minIndex = start;
int inc = 0, dec = 0;
for(int i = start + 1;i <= end;i++){
if(height[i] < height[minIndex]) minIndex = i;
if(height[i] > height[i - 1]) inc++;
else if(height[i] < height[i - 1]) dec--;
}
int res = 0;
if(dec == 0){
for(int i = start;i <= end;i++){
int min = Math.min(height[i], (end - i + 1));
res = Math.max(res, min * min);
}
}
else if (inc == 0){
for(int i = start;i <= end;i++) {
int min = Math.min(height[i], (i - start + 1));
res = Math.max(res, min * min);
}
}
else{
int min = Math.min(height[minIndex], (end - start + 1));
res = Math.max(
Math.max(helperCore(height, minIndex + 1, end), helperCore(height, start, minIndex - 1)),
min * min);
}
return res;
}
}
题目3
题目背景是奥特曼打小怪兽。有一个由0,1,2以及大于2的数字组成的矩阵,0表示陷阱,1表示陆地,奥特曼不可以走陷阱,可以走陆地,2以及大于2的数字表示奥特曼的等级,数字越大等级越高。奥特曼从矩阵的左上角(0,0)位置出发,只能由等级从弱到强去打小怪兽,每打完一个小怪兽,小怪兽所在的位置就变成了陆地。问奥特曼能不能打完所有的小怪兽。可以打完输出最少步数,否则输出-1;
约束1:奥特曼遇到可以打的小怪兽不可以不打
AC代码
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()){
}
}
}