最右10.22笔试

题目1
import java.util.Random;
import java.util.Scanner;

/**
 * @author wanna
 * @version v1.0
 * @Package com.wanna.main45
 * @date 2021/10/19 8:19 下午
 */
public class Main {
    /*
        @ 最右1
        找到一个数组中第一个缺少的正数
        比如arr=[-3,2,3],缺少的第一个正数为1
        比如arr[-3,1,3],缺少的第一个正数是2
     */

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = scanner.nextInt();
        }
        quickSort(arr);  // 先使用快排按照从小到大去进行排序
//        mergeSort(arr);

        // 如果最后一个元素都<=0,那么直接输出1
        if (arr[N - 1] <= 0) {
            System.out.println(1);
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            // 如果arr[i]<=0 并且arr[i+1]<=0,那么continue,还不是我们应该讨论的
            if (i + 1 < arr.length && arr[i] <= 0 && arr[i + 1] <= 0) {
                continue;
            }
            // 如果arr[i]<=0并且arr[i+1]>0,也就是先出现了负数(含0),然后出现了正数
            // 需要讨论arr[i+1]是否为1,如果为1,continue,不是1直接输出1,因为一定缺少1
            if (i + 1 < arr.length && arr[i] <= 0 && arr[i + 1] > 0) {
                // 如果arr[i+1]是1的话,那么continue
                // 比如-2 1这种,因为下一个是1,不会缺少1,那么continue
                // 如果arr[i+1]不是1,比如-2 2,因为下一个是2,所以必然缺少1,进行输出
                if (arr[i + 1] == 1) {
                    continue;
                }
                // 如果这个元素不是1,那么输出1
                System.out.println(1);
                return;
            }
            // 如果arr[i]>0并且arr[i+1]>0,也就是两个正数的情况
            // 1.如果arr[i]==arr[i+1],那么它之间并不缺少元素,continue
            // 2.如果arr[i]+1==arr[i+1],之间也是不缺少元素,continue
            if (i + 1 < arr.length && arr[i] > 0 && arr[i + 1] > 0) {
                // 如果两者相等的话,那么continue
                // 如果当前元素+1=下一个元素,那么continue,因为之间不可能缺了元素
                if (arr[i] == arr[i + 1] || arr[i] + 1 == arr[i + 1]) {
                    continue;
                }
                System.out.println(arr[i] + 1);
                return;
            }
        }
        // 有可能一个数组中所有元素都为正数,有可能全部都为负数
        // 如果全部为负数,在上面已经处理过了,这里只需要处理全是正数并且不还不符合缺少了数的情况,需要输出arr[N-1]+1
        System.out.println(arr[N - 1] + 1);
    }

    public static void mergeSort(int[] arr) {
        mSort(arr, 0, arr.length - 1, new int[arr.length]);
    }

    public static void mSort(int[] arr, int left, int right, int[] temp) {
        if (right <= left) {
            return;
        }
        int mid = left + ((right - left) >> 1);
        mSort(arr, left, mid, temp);
        mSort(arr, mid + 1, right, temp);
        merge(arr, left, mid + 1, right, temp);
    }

    public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
        int L = left, R = mid, index = L;
        for (; L < mid && R <= right; ) {
            temp[index++] = arr[L] > arr[R] ? arr[R++] : arr[L++];
        }
        for (; L < mid; ) {
            temp[index++] = arr[L++];
        }
        for (; R <= right; ) {
            temp[index++] = arr[R++];
        }
        System.arraycopy(temp, left, arr, left, right - left + 1);
    }

    public static void quickSort(int[] arr) {
        qSort(arr, 0, arr.length - 1);
    }

    public static void qSort(int[] arr, int left, int right) {
        if (right <= left) {
            return;
        }
        int random = left + new Random().nextInt(right - left + 1);
        swap(arr, random, right);
        int[] partition = partition(arr, left, right);
        qSort(arr, left, partition[0] - 1);
        qSort(arr, partition[1] + 1, right);
    }

    public static int[] partition(int[] arr, int left, int right) {
        int pivlot = arr[right];
        int less = left - 1;
        int more = right;
        for (; left < more; ) {
            if (arr[left] < pivlot) {
                swap(arr, left++, ++less);
            } else if (arr[left] > pivlot) {
                swap(arr, left, --more);
            } else {
                left++;
            }
        }
        swap(arr, right, more);
        return new int[]{less + 1, more};
    }

    public static void swap(int[] arr, int i, int j) {
        if (arr[i] == arr[j]) {
            return;
        }
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
}

题目2
import java.util.Scanner;

/**
 * @author wanna
 * @version v1.0
 * @Package com.wanna.main46
 * @date 2021/10/19 8:20 下午
 */
public class Main {
    /*
        @最右2 AC 80% TLE
        一共有N层
        第一行会输入N,代表学生的层数
        第二行会输入每一层的学生数量,比如[1,2,3]代表第一层有1个学生,第二层有2个学生,第三层有3个学生
        第二行之后会输入N行
        每一行的第一个数代表的是第i层的人向上走一层的体力消耗,每一行的第二个数代表第i层的人向下走一层的体力消耗
        如果走向上走j层/向下走j层,那么就得j*对应的体力消耗

        要选定一个k,代表最终要开会的层数,要求的是所有学生到k的体力消耗总数最小
        最终要输出的就是最小的消耗体力的数量
     */

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int N = scanner.nextInt();  // 行数,也就是对应的行数
        int[] arr = new int[N];
        for (int i = 0; i < N; i++) {
            arr[i] = scanner.nextInt();  // 每一层的学生的个数
        }
        int[][] consume = new int[N][2];
        for (int i = 0; i < N; i++) {
            consume[i][0] = scanner.nextInt();  // 第i层的人向上走的一层单位体力消耗
            consume[i][1] = scanner.nextInt();  // 第i层的人向下走的一层单位体力消耗
        }
        process(consume, arr, N);
    }


    // 可以向上走,可以向下走,求所有学生的最小的体力消耗
    // AC 80% 然后TLE(时间超出)了...整体时间复杂度在O(n^2)
    public static void process(int[][] consume, int[] arr, int N) {

        int min = Integer.MAX_VALUE; // 初始化一个min代表最终需要输出的最小体力消耗
        // 如果开会选在第i层的话,最后的总消耗是多少呢?
        for (int i = 0; i < N; i++) {
            int currentConsume = 0; // currentConsume代表选在i层开会最终的体力消耗

            // 在i层以上的学生走到第i层的最终总消耗
            for (int j = i + 1; j < N; j++) {
                // j-i获取的是第j层楼到第i层楼差了几层楼
                // consume[j][1]也就是1个人向下走1层需要进行的消耗
                // arr[j]代表的是第j层的学生消耗体力的数量
                currentConsume += (j - i) * consume[j][1] * arr[j];
            }

            // 在i层以下的学生走到第i层的最终总消耗,分析过程和在i层以上的学生走到第i层的最终总消耗完全类似
            for (int j = i - 1; j >= 0; j--) {
                currentConsume += (i - j) * consume[j][0] * arr[j];
            }
            // 如果选用当前i层的最终消耗比以前的消耗低了,那么就得更新最终的结果
            min = Math.min(currentConsume, min);
        }
        System.out.println(min);
    }
}


#最右笔试##笔经##最右#
全部评论
#前缀和#上下楼最小花费
点赞 回复 分享
发布于 2022-07-26 16:10
请问一下有两道笔试题目原题吗
点赞 回复 分享
发布于 2021-10-22 18:52
第一题不会搞,我弄了个int[1000],然后存,过了
点赞 回复 分享
发布于 2021-10-22 17:46
有面试通知了吗
点赞 回复 分享
发布于 2021-10-22 16:16
只A出了第一题😥
点赞 回复 分享
发布于 2021-10-22 09:26

相关推荐

#实习# #面经# #百度# 面试时长:&nbsp;62分钟面试岗位:&nbsp;C++/Go后端开发1.&nbsp;业务介绍2.&nbsp;自我介绍3.&nbsp;实习-&nbsp;你的经历里提到了提升I/O性能的工作,可以介绍一下吗-&nbsp;测试相关工作,有什么比较有挑战性的吗4.&nbsp;八股-&nbsp;介绍一下C++中的extern关键字,(&nbsp;extern&nbsp;C,extern函数/变量)-&nbsp;介绍一下C++中的const关键字&nbsp;(函数返回值/变量,修饰类成员函数)-&nbsp;C++中const变量和宏变量有什么区别,是否会为宏变量分配空间-&nbsp;介绍一下C++中static关键字,static的类函数对不同类成员变量的访问情况是怎么样的-&nbsp;C++会为空类自动哪些函数?一个空类的大小是多少,为什么?-&nbsp;介绍一下C++中的this指针,是否能获取它的地址,是否能给它赋值?-&nbsp;C++是如何实现多态的?基类的虚函数派生类是否必须要实现?纯虚函数是什么?能否生成一个纯虚类的对象?是否可以用一个派生类的指针指向基类的对象?-&nbsp;C++中普通函数是否可以声明为virtual?static&nbsp;函数是否可以声明为virtual?类构造函数和析构函数是否可以声明为virtual?-&nbsp;C++中new/delete和malloc/free有什么区别,申请空间失败后,new和malloc的返回值有什么区别-&nbsp;哪些情况下会发生段错误?怎么排查一个C++程序中的段错误(检测排查工具,代码分析)-&nbsp;core&nbsp;dump文件是什么?如何利用core&nbsp;dump文件排查问题(用什么指令)-&nbsp;Linux中用什么指令去分析CPU和内存高占用的程序?如何对这些字段进行排序?-&nbsp;介绍一下几种智能指针-&nbsp;介绍一下左值和右值、左值引用和右值引用。能否把右值进行&amp;amp;quot;赋值&amp;amp;quot;?(移动语义)-&nbsp;介绍一下引用折叠。为什么需要引用折叠?为什么需要完美转发?-&nbsp;介绍一下TCP的三次握手和四次挥手-&nbsp;DDoS之类的攻击涉及针对TCP握手或者挥手过程中的攻击,主要是针对握手还是挥手?针对握手的哪一步?攻击主要影响服务器的什么资源?有哪些防范手段?-&nbsp;介绍一下常见的http状态码(2开头的,4开头的)5.&nbsp;手撕:&nbsp;实现前缀字典树和必要的函数
点赞 评论 收藏
分享
评论
3
9
分享

创作者周榜

更多
牛客网
牛客企业服务