【笔试强训】Week5:空调遥控, kotor和气球,走迷宫,主持人调度II,体操队形,二叉树的最大路径和,排序子序列,消减整数

文章目录

1. 空调遥控

空调遥控

题目描述

解题思路

解法一:滑动窗口

时间复杂度:O(n * lonn) + O(n)

把数组排序,维护一个窗口,保证max-min<=2p,统计窗口长度,返回最大值

解法二:二分查找

时间复杂度:O(n * lonn ) + O(n * lonn )

把数组排序,枚举每一个温度,通过二分查找,分别找到arr[i]-parr[i]+p对应的下标,计算这个区间内人数总和,返回最大值即可

代码实现

java 复制代码
import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static Read in = new Read();
    static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    public static void main(String[] args) throws IOException{
        int n = in.nextInt();
        int p = in.nextInt();

        long[] arr = new long[n];
        for(int i= 0;i<n;i++)
            arr[i] = in.nextLong();
        Arrays.sort(arr);
        
        int left = 0;
        int right = 0;
        int ret = 0;
        
        while(right<n){
            while(left<=right && (arr[right]-arr[left])>2*p)
                left++;
            ret = Math.max(right-left+1,ret);
            right++;
        }
        System.out.println(ret);
        out.close();
    }
}



class Read{
    StringTokenizer st = new StringTokenizer("");
    BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

    String next() throws IOException{
        while(!st.hasMoreTokens()){
            st = new StringTokenizer(bf.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws IOException{
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException{
        return Long.parseLong(next());
    }

}

2. kotori和气球

kotori和气球

题目描述

解题思路

排列组合

第一个位置n种选择,其余位置n-1种选择

代码实现

java 复制代码
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        
        int n = in.nextInt();
        int m = in.nextInt();
        int ans = n;
        for(int i = 1;i<m;i++){
            ans=ans*(n-1)%109;
        }
        System.out.println(ans);
    }
}

3. 走迷宫

走迷宫

题目描述

解题思路

最短路径 --》 BFS

注意: 下标从1开始,字符串要先前置一个" " 再填写到grid中

代码实现

java 复制代码
import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    static Read in = new Read();
    public static void main(String[] args) throws IOException {
        int n = in.nextInt();
        int m = in.nextInt();
        int xs = in.nextInt();
        int ys = in.nextInt();
        int xt = in.nextInt();
        int yt = in.nextInt();
        int[] dx = {0, 0, 1, -1};
        int[] dy = {1, -1, 0, 0};

        if (xs == xt && ys == yt) {
            System.out.println(0);
            return;
        }

        boolean[][] check = new boolean[n + 1][m + 1];
        char[][] grid = new char[n + 1][m + 1];

        for (int i = 1; i <= n; i++) {
            String str = in.next();
            str = " "+str;
            grid[i] = str.toCharArray();
        }

        int ans = 0;
        Queue<int[]> queue = new LinkedList<>();
        queue.add(new int[] {xs, ys});
        check[xs][ys] = true;

        while (!queue.isEmpty()) {
            ans++;
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] top = queue.poll();
                for (int k = 0; k < 4; k++) {
                    int x = dx[k] + top[0];
                    int y = dy[k] + top[1];
                    if (x > 0 && x <= n && y > 0 && y <= m && !check[x][y] && grid[x][y] == '.') {
                        if (x == xt && y == yt){
                            System.out.println(ans);
                            return ;
                        }
                        queue.add(new int[] {x, y});
                        check[x][y] = true;
                    }
                }
            }
        }
        System.out.println(-1);
    }

}

class Read {
    StringTokenizer st = new StringTokenizer("");
    BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

    String next() throws IOException {
        while (!st.hasMoreTokens()) {
            st = new StringTokenizer(bf.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException {
        return Long.parseLong(next());
    }

}

4. 主持人调度II

主持人调度II

题目描述

解题思路

  1. 把所有数组按照第一个元素排序
  2. 创建一个列表,表示已分配的数组。
  3. 放入第一个数组,接着遍历数组,如果可以与已分配的数组时间错开,就可以继续排在后面。如果与所有已分配的数组都重合,就再添加一个子列表
  4. 结果就是列表的长度

优化:

  1. 子列表中不需要存放放已分配好的数组的右端点的最大值
  2. 每次遍历列表时间复杂度太高,可以把列表设置成小根堆,每次与堆顶元素比较即可

代码实现

java 复制代码
public int minmumNumberOfHost (int n, int[][] startEnd) {
        // write code here
        Arrays.sort(startEnd, (a, b)->Integer.compare(a[0], b[0]));
        PriorityQueue<Integer> heap = new PriorityQueue<>();
        heap.add(startEnd[0][1]);

        for (int i = 1; i < n; i++) {
            int top = heap.peek();
            if(startEnd[i][0] >= top){
                heap.poll();
                heap.add(startEnd[i][1]);
            }else
                heap.add(startEnd[i][1]);

        }
        return heap.size();

    }

5. 体操队形

体操队形

题目描述

解题思路

DFS + 枚举

通过决策树来枚举所有情况,剪枝不合法的情况:

  1. 通过vis数组记录每个数字是否被使用过
  2. 以下面为例,2要求排在1前面,当1已经排队,2还没排队,所有情况都不可能成立,所以1先排队的情况都要剪枝。

代码实现

java 复制代码
import java.util.*;

public class Main{
    static boolean[] vis;
    static int[] arr;
    static int n = 0;
    static int ret = 0;
    
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        arr = new int[n+1];
        vis = new boolean[n+1];
        for(int i = 1;i<=n;i++){
            arr[i] = in.nextInt();
        }        
        
        dfs(1);
        System.out.println(ret);
    }
    
    static void dfs(int pos){
        if(pos==n+1){
            ret++;
            return;
        }
        
        for(int i = 1;i<=n;i++){
            if(!vis[i] && (arr[i]==i || !vis[arr[i]])){
                vis[i] = true;
                dfs(pos+1);
                vis[i] = false;
            }
        }
    }
}

6. 二叉树的最大路径和

二叉树的最大路径和

题目描述

解题思路

树形dp + DFS

  • 在某个子树上整合的信息:经过根节点的最大路径和
  • 左子树:返回以左孩子为根节点的最大单链路径和,如果最大和是负数,可以直接舍弃
    • left = Math.max(0,dfs(root.left))
  • 右子树:返回以右孩子为根节点的最大单链路径和

因为最终的统计如果要包含根节点,所以左右子树的路径必须是单链,再拼接上根节点,才能得到以经过根节点的最大路径和。

每次得到的路径和中取最大值,是最终的结果.

代码实现

java 复制代码
import java.util.*;
public class Solution {
     int ret = -1010;
    public int maxPathSum (TreeNode root) {
        // write code here
        dfs(root);
        return ret;
    }

    int dfs(TreeNode root){
        if(root==null)
            return 0;

        int left = Math.max(0,dfs(root.left));
        int right = Math.max(0,dfs(root.right));

        ret = Math.max(ret,left+right+root.val);
        return Math.max(left,right)+root.val;
    }
}

7. 排序子序列

排序子序列

题目描述

解题思路

贪心+模拟

定义一个指针,先判断当前是上升或者下降,如果是上升,就让指针一直向后移动到波峰,下降同理,指针不再移动时统计结果。

如果当前阶段是水平,只移动指针,不统计结果,让这段水平区域与后面上升或下降的部分连到一起

代码实现

java 复制代码
import java.util.*;
import java.io.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) throws IOException {
        Read in = new Read();
        int n = in.nextInt();
        int[] arr = new int[n];
        for(int i= 0;i<n;i++){
            arr[i] = in.nextInt();
        }

        int ret = 0;
        int i = 0;
        while(i<n){
            if(i==n-1){
                ret++;
                break;
            }
            if(arr[i]<arr[i+1]){
                while(i<n-1 && arr[i]<=arr[i+1])
                    i++;
                ret++;
            }else if(arr[i]>arr[i+1]){
                while(i<n-1 && arr[i]>=arr[i+1])
                    i++;
                ret++;
            }else{
                 while(i<n-1 && arr[i]==arr[i+1])
                    i++;
            }
            i++;
        }
        System.out.println(ret);
    }
}
class Read {
    StringTokenizer st = new StringTokenizer("");
    BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));

    String next() throws IOException {
        while (!st.hasMoreTokens()) {
            st = new StringTokenizer(bf.readLine());
        }
        return st.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException {
        return Long.parseLong(next());
    }

}

8. 消减整数

消减整数

题目描述

解题思路

贪心

每次尽可能减去之前数的两倍:假设x-a得到y,如果y%2a==0,说明y可以一直-2a得到0;否则就-a

代码实现

java 复制代码
import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int t = in.nextInt();
        while(t>0){
            int h = in.nextInt();
            h-=1;
            int a = 1;
            int ans = 1;
            while(h>0){
                if(h%(2*a)==0){
                    h-=2*a;
                    a*=2;
                }else
                    h-=a;
                ans++;
            }
            System.out.println(ans);
            t--;
        }
    }
}
相关推荐
云烟成雨TD1 分钟前
Agent Scope Java 2.x 系列【6】消息层
java·人工智能·agent
云烟成雨TD2 分钟前
Spring AI Alibaba 1.x 系列【74】Agentic RAG 与混合 RAG
java·人工智能·spring
小刘|4 分钟前
Spring AI 结构化输出 + 大模型参数全解(含千问调优)
java·后端·spring
云烟成雨TD5 分钟前
Spring AI Alibaba 1.x 系列【79】图执行生命周期的可观测性基础设施
java·人工智能·spring
霸道流氓气质9 分钟前
Java 单元测试生成大量 Excel 测试数据实战指南
java·单元测试·excel
MicroTech20259 分钟前
量子隐形传态路线的瓶颈与突破,微算法科技(MLGO)以技术创新助力量子通信长距离组网
科技·算法·量子计算
洛水水9 分钟前
【力扣100题】89.下一个排列
数据结构·算法·leetcode
洛水水10 分钟前
【力扣100题】90.寻找重复数
算法·leetcode·职场和发展
io无心14 分钟前
基于Image 2的多配件商品图生成技术实现(已开源)
java·image2
鱼子星_16 分钟前
【数据结构】排序的拓展——快速排序的生态多样性与归并排序沾染文件操作
c语言·数据结构·算法