华为机试整理3.25

3.25 华为机试整理

第一题 两个ip地址是否是同一个网段

实际上十进制就可以进行&操作,无需转换为二进制操作,将题目做的复杂了,将地址在 '.‘ 处分开,分段与然后比较即可

import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            //  四段全部分开
            String[] ip1 = sc.next().split("\\.");
            String[] ip2 = sc.next().split("\\.");
            String[] dns = sc.next().split("\\.");
            int flag = 1;
            String[] res = new String[4];
            // 可以直接&,并不需要转换成二进制
            for(int i = 0; i < 4; i++){
                //  一段不相等,即不相等
                res[i] = String.valueOf( Integer.valueOf(ip1[i]) & Integer.valueOf(dns[i]) );
                String temp = String.valueOf( Integer.valueOf(ip2[i]) & Integer.valueOf(dns[i]) );
                if(!res[i].equals(temp)){
                    flag = 0;
                    break;
                }
            }
            System.out.print(flag == 1);
            StringBuffer outs = new StringBuffer();

            for(String s : res){
                outs.append(s);
                outs.append(".");

            }
            outs.deleteCharAt(outs.length() - 1);
            System.out.println(" ");
            System.out.print(outs.toString());

        }
    }
}

注意的是使用split的时候,‘.’符号是特殊符号,故之前要加上两个\\代表是原始字符

第二题 全是1的最大子矩阵

思路: 机试的时候想的是,将框定范围从原矩阵边的长度往下递减,然后框定出所有对应长度的矩阵,再遍历一遍,判断是否全是1。

public class Main{
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int N = sc.nextInt();
            int[][] matrix = new int[N][N];
            // 矩阵初始化
            for(int i = 0; i< N; i++){
                String line = sc.next();
                for(int j = 0; j < N; j++){
                    if(line.charAt(j) == '0') {
                        matrix[i][j] = 0;
                    }else
                        matrix[i][j] = 1;
                }
            }
            // l代表边长
            int l = N;
            while(l > 1) {
                int flag = 0;
                for (int i = 0; i + l <= N; i++){
                    for(int j = 0; j + l <= N; j++){
                        if(ifMatrix(matrix, l, i, j) ){
                            flag = 1;
                            break;
                        }
                    }
                    if(flag == 1){
                        break;
                    }
                }
                if(flag == 1) {
                    System.out.println(l*l);
                    break;
                }
                l--;
            }

            if(l == 1) System.out.println(1);
        }
    }

    private static boolean ifMatrix(int[][] matrix, int l, int x, int y){
        // 本来很简单的设计,总是用的很复杂,甚至加上了flag。实际上过程种出问题,直接返回false即可
        int flag = 1;
        for(int i = x; i < l; i++){
            for(int j = y; j < l; j++){
                if(matrix[i][j] == 0){
                  return false;
                }
            }
        }
        return true;
    }
}

break 只跳出一层循环,一定要注意! 注意代码的设计,能简洁就尽量简洁。

快捷的思路想法

先对数组做预处理,将每列中的连续1,从1开始升序重新赋值。如果断开赋值从1重新开始

然后遍历每行,行元素存的是高度h,那么连续h个值为h的行元素就确立了一个边长为h的正方形!
在这里插入图片描述
思路学习来源 : https://blog.csdn.net/zuzhiang/article/details/78693421

第三题 sjf作业调度

做的时候,就打算纯粹模拟过程,每次做第一个处理机上任务,更新后续处理机时间,采用队列的形式描述处理机,且任务提前升序排列。缺点就是:做的不够快,一直再考虑机制怎么模拟。

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            int m = sc.nextInt();
            int n = sc.nextInt();
            LinkedList<Integer> cpu = new LinkedList<>();
            int[] works = new int[n];   // 作业时长
            for(int i = 0; i < n; i++){
                int work = sc.nextInt();
                works[i] = work;
            }
            Arrays.sort(works);

            int sum = 0;
            // 如果作业数小于处理机数,则最长时间的任务,就是总完成时间
            if(m>n) System.out.println(works[n-1]);
            else {
                for (int i = 0; i < m; i++) {
                    cpu.offer(works[i]);

                }
                int idx = m - 1;
                while(idx < n){
                    int t;
                    // 第一批先进入处理机
                    if(cpu.size() > 0)
                        t = cpu.peek();
                    else
                        break;
                    sum += t;
                    int addNum = 0;
                    // 对每个处理机进行减去时间处理
                    for(int i = 0; i < cpu.size(); i++){
                        System.out.println("这轮消耗时间: " + t);
                        System.out.println(i+"更新前;");
                        for(Integer num : cpu){
                            System.out.print(num + " ");
                        }
                        if(cpu.get(i) - t == 0) addNum++;
                        cpu.set(i, cpu.get(i) - t);
                        System.out.println("更新后;");
                        for(Integer num : cpu){
                            System.out.print(num + " ");
                        }
                        System.out.println();

                    }
                    // 将所有时间化为0的处理机进行移除操作,并且加入新的任务
                    for(int i = 0; i< addNum; i++){
                        cpu.poll();
                        if(idx + 1 < n){
                            System.out.println("进入了: " + works[idx+1]);
                            cpu.offer(works[++idx]);
                        }
                    }
                }
                // 一旦要任务不够分的时候,若队列中还有任务时,就将最长时间的任务,视为最后执行的时间加上
                if(cpu.size() > 0)sum += cpu.get(cpu.size() -1);
                // 机试时这个语句写在了if框外,可能就是m>n样例出错的情况!
                System.out.println(sum);
            }
        }
    }
}

样例没有全通过,在m>n的时候,也将sum输出了,实际输出语句应该放在sum内部

发布了2 篇原创文章 · 获赞 0 · 访问量 318
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览