第3天:最近笔试编程题汇总

时间:2022-07-24
本文章向大家介绍第3天:最近笔试编程题汇总,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

笔试概述

  首先跟大家说声抱歉,由于最近有面试和笔试,所以一直刷题就没时间更新博客了。随着秋招进入了一个白热化阶段,我们所投的岗位也已经进入了面试和笔试阶段。最近的笔试好几场,就一些编程题做一些简单的总结,方便同学参考。当然也方便自己学习。最近笔试的大厂有百度、网易互娱、中原银行。

各大公司的编程题

一、中原银行笔试

1、求x到y的最少计算次数 (1)、题目描述:

给定两个-100到100的整数x和y,对x只能进行加1,减1,乘2操作,问最少对x进行几次操作能得到y? 例如: a=3,b=11: 可以通过322-1,3次操作得到11; a=5,b=8:可以通过(5-1)*2,2次操作得到8;

(2)、输入描述:

输入以英文逗号分隔的两个数字,数字均在32位整数范围内。

(3)、输出描述:

输出一个数字

(4)、示例1

输入 3,11 输出 3

(5)、解题思路:

直接用暴力法,其实数据量不大,可以承受的。具体用java实现。

import java.util.Scanner;

public class Main1 {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        String[] nums = s.split(",");
        int a = Integer.parseInt(nums[0]);
        int b = Integer.parseInt(nums[1]);

        int ans = solution(a,b);
        System.out.println(ans);
    }

    private static int solution(int a, int b){

        int ans = 0;
        // 特殊值
        if(a == 0 && b <= 0) return Math.abs(b);
        if(a == 0 && b > 0) return minOps(1,b) + 1;

        // a b 同号
        if(a * b > 0){
            a = Math.abs(a); b = Math.abs(b);
            if(a >= b) return a - b;
                // a < b
            else return minOps(a,b);
        }
        // a b 异号
        // 如果 a 是负值,将 a 转换为正值 1,则 a * b > 0,调用自身得到结果。
        if(a < 0) return ans - a + 1 + solution(1,b);
        // 如果 b 是负值,将 b 转换为正值 1。
        return ans - b + 1 + solution(a,1);
    }

    private static int minOps(int a, int b){

        if(b >= a && b <= (a << 1))
            return Math.min(b - a,(a << 1) - b + 1);
        if((b & 1) == 1)
            return Math.min(minOps(a,(b + 1) >> 1), minOps(a,(b - 1) >> 1)) + 2;
        return minOps(a,b >> 1) + 1;
    }
}

具体的结果如图所示

当然我们也可以用深度优先搜索

import java.util.Scanner;
public class Main2 {
        static Scanner sc = new Scanner(System.in);
        static String s[] = sc.next().split(",");
        static int x = Integer.valueOf(s[0]);
        static int y = Integer.valueOf(s[1]);
        static int min = Math.abs(x - y);//最小值的上界
        public static void main(String[] args) {
            dfs(x, y, 0);
            System.out.println(min);
        }
        private static void dfs(int x, int y, int count) {
            if (count == min)
                return;
            if (x == y){
                min = count;
                return;
            }
            dfs(x + 1, y, count + 1);
            dfs(x - 1, y, count + 1);
            dfs(x * 2, y, count + 1);
        }
}

具体的结果如图所示

当然我们也可以用广度优先搜索

import java.util.*;
public class Main {
    static class Node{
        private int value; //结的值
        private int depth;//结点的深度
        private ArrayList<Node> nodes;//子结点
        //构造函数
        public Node(int value,int depth){
            this.value = value;
            this.depth = depth;
        }
    }
    public static void main(String[] args){
        //获取a,b的值
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int a = Integer.parseInt(str.split(",")[0]);
        int b = Integer.parseInt(str.split(",")[1]);
        //存入头结点,并初始化队列和hashSet
        Node head  = new Node(a,0);
        Queue<Node> queue = new LinkedList<>();
        HashSet<Node> set = new HashSet<>();
        queue.add(head);
        set.add(head);
        while(!queue.isEmpty()){
            head = queue.poll();
            //找到该值后,输出并结束main()方法
            if(head.value == b){
                System.out.println(head.depth);
                return;
            }else{
                //没有找到该值,则在这个节点后面添加3个子结点,分别是值+1,值-1,值*2. 结点的深度+1;
                ArrayList<Node> nodes = new ArrayList<>();
                nodes.add(new Node(head.value+1,head.depth+1));
                nodes.add(new Node(head.value-1,head.depth+1));
                nodes.add(new Node(head.value*2,head.depth+1));
                head.nodes = nodes;
            }
            //将当前结点的所有子结点压入队列,hashSet的作用是防止同一个结点被遍历压入队列两次.
            for(Node node : head.nodes){
                if(!set.contains(node)){
                    queue.add(node);
                    set.add(node);
                }
            }

        }

    }
}

具体的结果如图所示

递归做法:首先需要把输入的两个数都变成正数(否则会Stackoverflow),如果两数异号则直接将第一个数归零,结果加上第一个数的绝对值。

import java.util.Scanner;

public class Main3 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] s = sc.nextLine().split(",");
        int a = Integer.parseInt(s[0]);
        int b = Integer.parseInt(s[1]);
        int res = 0;
        if(a*b<0){
            res = Math.abs(a);
            a = 0;
        }
        a=Math.abs(a);
        b=Math.abs(b);
        System.out.print(helper(a,b,res));
    }
    public static int helper(int a, int b, int res){
        if(a==b) return res;
        if(a!=0 && Math.abs(2*a+2)<Math.abs(b)) return Math.min(helper(a+1,b,res+1),helper(a*2,b,res+1));
        else if(Math.abs(a+1-b)<Math.abs(a-1-b) && Math.abs(a+1-b)<Math.abs(a*2-b)) return helper(a+1,b,res+1);
        else if(Math.abs(a+1-b)>Math.abs(a-1-b) && Math.abs(a-1-b)<Math.abs(a*2-b)) return helper(a-1,b,res+1);
        else return helper(a*2,b,res+1);
    }
}

具体的结果如图所示:

#bfs这是一个最小路径的搜索问题,第一时间想到这个,这里多加了一列用来储存位置,用Python实现如下:

def bfs(quene,b):
    while quene:
        x = quene.pop(0)
        if x[0]==b:
            return x[1]
        else:
            quene.append([x[0]+1,x[1]+1])
            quene.append([x[0]-1,x[1]+1])
            quene.append([x[0]*2,x[1]+1])
if __name__=="__main__":
    a,b = map(int,input().strip().split(','))
    quene = []
    quene.append([a,0])
    print(bfs(quene,b))

具体的结果如图所示:

2、质数之和等于某个数 (1)、题目描述 给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输入值小于1000。如,输入为10,程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))。 (2)、解题思路

直接用暴力法

public class PrimeNumber {
    protected boolean isPrimeNumber(int num){
        if(num == 2) return true;//2特殊处理
        if(num < 2 || num % 2 == 0) return false;//识别小于2的数和偶数
        for(int i=3; i<=Math.sqrt(num); i+=2){
            if(num % i == 0){//识别被奇数整除
                return false;
            }
        }
        return true;
    }

    //获取质数和的个数
    public int getPNSum(int num) throws Exception{
        if(num < 1 || num >= 1000){
            throw new Exception("请输入正整数并小于1000");
        }
        int sum = 0;
        //单独考虑2
        if(isPrimeNumber(num - 2)){
            ++sum;
        }
        for(int i=3; i<=(num/2); i+=2){
            if(isPrimeNumber(i) && isPrimeNumber(num - i)){
                ++sum;
            }
        }
        return sum;
    }

    //测试代码
    public static void main(String[] args) {
        try {
            PrimeNumber pn = new PrimeNumber();
            int sum = pn.getPNSum(10);
            System.out.println("结果:"+sum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

具体的结果如图所示:

当然,我们可以用python中的math库和traceback库来实现,具体实现如下:

import math
import traceback

num = input('请输入一个正整数:')
ll = []
try:
    num = int(num)
except Exception as e:
    print(e)
    traceback.print_exc()
    # '类型输入错误,请输入正整数!'
else:
    for i in range(2, num):
        for j in range(2, int(math.sqrt(i)) + 1):
            if i % j == 0:
                break
        else:
            ll.append(i)
    print('ll:', ll)
    print(len(ll))
    result = []
    for i in ll:
        for j in ll:
            if i + j == num:  # 或者加条件 i<=j 确保结果不重复
                result.append((i, j))
    # print(result)
    # 去重
    result = [tuple(sorted(i)) for i in result]
    print(len(result))
    print(set(result))
    print(len(set(result)))

具体的结果如图所示:

最为简答的实现方法,用python实现如下:

def IsZhishu(n):
    if n>1:
        for i in range(2,n):
            if n%i==0:
                return False
        return True
if __name__ == '__main__':
    num = int(input("输入一个数"))
    result=0
    for i in range(num//2+1):
        tmp=num-i
        if IsZhishu(i) and IsZhishu(tmp):
            print("质数和",i,tmp)
            result+=1
    print(result)

具体的结果如图所示:

最简单用java实现如下

import java.util.Scanner;

public class Main4 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            System.out.println(Solve(n));
        }
    }

    public static int Solve(int n) {
        int sum = 0;
        for (int i = 2; i <= n / 2; i++) {
            if (isZhiShu(i) && isZhiShu(n - i))
                sum++;
        }
        return sum;
    }
    //判断是否质数
    public static boolean isZhiShu(int m) {
        for (int i = 2; i < Math.sqrt(m); i++) {
            if ((m % i) == 0)
                return false;
        }
        return true;
    }
}

具体的结果如图所示:

二、网易互娱

1、矩形重叠 (1)、题目描述

平面内有n个矩形,第i个矩形的左下角坐标为(x1 [i],y1 [i]),右上角坐标为(x2 [i],y2 [i])。如果两个或多个矩形有公共区域则认为它们是相互重叠的(不考虑边界和角落)。请你计算出平面内重叠的矩形数量最多的地方,有多少个矩形相互重叠。

(2)、输入描述:

输入包括五行。 第一行包括一个整数n(2 <= n <= 50),表示矩形的个数。 第二行包括n个整数x1 [i](-10 ^ 9 <= x1 [i] < = 10 ^ 9),表示左下角的横坐标。 第三行包括ñ个整数Y1 [I]( - 。10 ^ 9 <= Y1 [I] <= 10 ^ 9),左下角表示纵的坐标 第四行包括n个整数x2 [i](-10 ^ 9 <= x2 [i] <= 10 ^ 9),表示右上角的横坐标。 第五行包括n个整数y2 [i](-10 ^ 9 <= y2 [i] <= 10 ^ 9),表示右上角的纵坐标。

(3)、输出描述

输出一个正整数,表示最多的地方有多少个矩形相互重叠,如果矩形都不互相重叠,输出1。

(4)、示例1

输入 2 0 90 0 90 100 200 100 200

输出 2

(5)解题思路

无论何种情况,重叠区域也是四条边组成。而且是取自与n的矩形中的四条。所以遍历边的交点即可。用java实现如下:

import java.util.*;
public class Work {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] x1 = new int[n];
        int[] y1 = new int[n];
        int[] x2 = new int[n];
        int[] y2 = new int[n];
        int xmin = Integer.MAX_VALUE;
        int xmax = Integer.MIN_VALUE;
        int ymin = Integer.MAX_VALUE;
        int ymax = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++)
            x1[i] = in.nextInt();
        for (int i = 0; i < n; i++)
            y1[i] = in.nextInt();
        for (int i = 0; i < n; i++)
            x2[i] = in.nextInt();
        for (int i = 0; i < n; i++)
            y2[i] = in.nextInt();
        int ans = 0;
        int cnt = 0;
        for (int x : x1)
            for (int y : y1) {
                for (int i = 0; i < n; i++) {
                    if (x >= x1[i] && x < x2[i] && y >= y1[i] && y < y2[i])
                        cnt++;
                }
                if (cnt > ans)
                    ans = cnt;
                cnt = 0;
            }
        System.out.println(ans);
    }
}

测试结果如下:

请注意重叠的矩形数量最多的地方:遍历所有可能包含的点,看一下有多少矩形包含它 注:重叠数量最多的地方肯定是一块矩形区域。误区:A和B交,B和C交,但是A不和C交— B同时和A,C交,但是重叠区域只为1,用python实现如下:

import sys
n=int(sys.stdin.readline().strip())
x1=list(map(int,sys.stdin.readline().strip().split()))
y1=list(map(int,sys.stdin.readline().strip().split()))
x2=list(map(int,sys.stdin.readline().strip().split()))
y2=list(map(int,sys.stdin.readline().strip().split()))
res = 1
for x in x1+x2:
    for y in y1+y2:
        cnt = 0
        for i in range(n):
            if x > x1[i] and y > y1[i] and x <= x2[i] and y <= y2[i]:
                cnt += 1
        res = max(res,cnt)
print(res)

测试效果如下:

2、二进制计数 (1)、题目描述:

为了确定他的确实掌握了二进制,你给他出了这样一道译文:给定N个非负整数,将这N个数字按照二进制下1的个数分类,二进制下1的个数相同的数字属于同一类。求最后一共有几类数字?

(2)、输入描述:

输入的第一行是一个正整数T(0 <T <= 10),表示样例个数。对于每一个样例,第一行是一个正整数N(0 <N <= 100),表示有多少个数字。接下来一行是N个由空格分隔的非负整数,大小不超过2 ^ 31 –1。

(3)、输出描述:

对于每一组样例,输出一个正整数,表示输入的数字一共有几类。

(4)、示例1

输入 1 5 8 3 5 7 2 输出 3

解题思路

这里计算一个数二进制1的个数;利用n&(n-1)计算;效率要高于普通计算方式;用java实现如下:

import java.util.*;
public class Main5 {
    public  static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();

        while(T>0){
            --T;
            int N=in.nextInt();
            Set<Integer> set = new HashSet<>();
            while(N>0){
                --N;
                int n=in.nextInt();
                set.add(cc(n));
            }
            System.out.println(set.size());
        }

    }
    public static int cc(int n){
        int count=0;
        while(n>0){
            count++;
            n=n&(n-1);
        }
        return count;
    }
}

测试结果如下

其实用最简单的方法,用Python实现如下

T = int(input())
for j in range(T):
    b = input()
    numbers = input()
    count = []
    number = [int(num) for num in numbers.split()]
    for i in number:
        count.append(bin(i).count('1'))
    else:
        print(len(set(count)))

测试结果如下:

三、百度

1、幸运N串 (1)、题目描述:

小A很喜欢字母N,他认为连续的N串是他的幸运串。有一天小A看到了一个全部由大写字母组成的字符串,他被允许改变最多2个大写字母(也允许不改变或者只改变1个大写字母),使得字符串中所包含的最长的连续的N串的长度最长。你能帮助他吗?

(2)、输入描述:

输入的第一行是一个正整数T(0 < T <= 20),表示有T组测试数据。对于每一个测试数据包含一行大写字符串S(0 < |S| <= 50000,|S|表示字符串长度)。 数据范围: 20%的数据中,字符串长度不超过100; 70%的数据中,字符串长度不超过1000; 100%的数据中,字符串长度不超过50000。

(3)、输出描述:

对于每一组测试样例,输出一个整数,表示操作后包含的最长的连续N串的长度。

(4)、示例1

输入 3 NNTN NNNNGGNNNN NGNNNNGNNNNNNNNSNNNN

输出 4 10 18

(5)、解题思路

有一种最为简单的解题思路,暴力法,具体用python实现

number = input()
for i in range(int(number)):
    a = input()
    b = []
    c = 0
    for j in a:
        b.append(j)
        if len(b) - b.count('N') >= 3:
            b.pop(0)
        c = max(c, len(b))
    print(c)

测试效果图如图所示:

用基本的动态规划即可,具体用java实现如下:

import java.util.Scanner;
public class Main6 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int T = scanner.nextInt();
        for (int t = 0; t < T; t++) {
            String string = scanner.next();
            int[] dp1 = new int[string.length() + 1];
            int[] dp2 = new int[string.length() + 1];
            int[] dp3 = new int[string.length() + 1];
            for (int i = 0; i < string.length(); i++) {
                if (string.charAt(i) != 'N') {
                    dp1[i + 1] = 0;
                    dp2[i + 1] = dp1[i] + 1;
                    dp3[i + 1] = dp2[i] + 1;
                } else {
                    dp1[i + 1] = dp1[i] + 1;
                    dp2[i + 1] = dp2[i] + 1;
                    dp3[i + 1] = dp3[i] + 1;
                }
            }

            int max = 0;
            for (int i = 0; i < dp3.length; i++) {
                max = Math.max(max, dp3[i]);
            }
            System.out.println(max);
        }
    }
}

测试结果如下

滑动窗口的思路来实现,不过我们得引入collections中的defaultdict库,具体实现python如下:

from collections import defaultdict
def findlong(arr):
    left = 0
    right = 0
    res = 0
    mymap = defaultdict(int)
    while right < len(arr):
        mymap[arr[right]] += 1
        right += 1
        while (right - left) - mymap['N'] > 2:
            mymap[arr[left]] -= 1
            left += 1

        res = max(res, right - left)
    return res
N = int(input())
for i in range(N):
    a = list(input())
    print(findlong(a))

测试结果如图所示:

2、游泳池 (1)、题目描述:

小明作为一个游泳池管理员,以玩弄给水管和排水管为乐,也因此产生了很多数学题考验小朋友。 现在小明想把这个行动升级,考验一下程序员,做了一个自动装置来控制给水管和排水管。在开始时,给水管和排水管都是打开状态的,并且游泳池里没有水。在自动装置的作用下,每经过t1分钟,给水管的状态都会改变,即从打开状态变为关闭状态或从关闭状态变为打开状态,而同时每经过t2分钟,排水管的状态也会改变。当给水管打开时,给水管每分钟会向游泳池里注入m1升水;当排水管打开时,排水管每分钟会把游泳池里水排走m2升;当给水管和排水管同时打开时,游泳池的水量变化为每分钟(m1-m2)升。当然泳池的水量不能变为负数,同时泳池也有个最大容量m,水量不能超过m升。那么经过t分钟后,游泳池里有多少升水?

(2)、输入描述:

输入第一行为一个正整数T,表示有T组数据。 每组数据的为一行包含六个整数,分别表示m, t, m1, t1, m2, t2。 数据范围: 对于所有数据,满足1<=T<=10, 1<=m<=100000, 1<=t<=86400, 1<=m1,m2<=100, 1<=t1,t2<=10。

(3)、输出描述:

对于每一个数据,输出一行,包括一个整数,为在t分钟后游泳池中的水量。

(4)、示例1

输入 5 10 2 1 5 2 5 10 2 10 5 2 5 10 2 3 5 2 5 100 100 3 4 4 3 10000 1000 10 5 5 3 输出 0 10 2 3 2495

(5)、解题思路

有一种最为简单的解题思路,暴力法,具体用python实现

import sys
T = int(sys.stdin.readline().strip())
data = []
for _ in range(T):
    row = [int(_) for _ in sys.stdin.readline().strip().split()]
    data.append(row)

for row in data:
    m, t, m1, t1, m2, t2 = row
    cur_m = 0
    inFlag = 0
    outFlag = 0
    for i in range(1, t + 1):

        inFlag = 1 if ((i - 1) // t1) % 2 == 0 else 0
        outFlag = 1 if ((i - 1) // t2) % 2 == 0 else 0

        cur_m += m1 * inFlag - m2 * outFlag
        if cur_m < 0:
            cur_m = 0
        if cur_m > m:
            cur_m = m

    print(cur_m)

测试效果图如图所示:

想减少循环次数我觉得可以通过求t1和t2的最小公倍数,在最小公倍数时间内水池蓄水量,然后t // 最小公倍数时间 * 期间蓄水量,然后再加余数时间的蓄水量。具体用python实现:

for i in range(int(input())):
    m,t,m1,t1,m2,t2 = map(int,(input()).split())
    c1 = 0
    c2 = 0
    water = 0
    for j in range(t):
        if j%t1 == 0:
            c1 = 1-c1
        if j%t2 == 0:
            c2 = 1- c2
        water = water +(m1*c1-m2*c2)
        if water <=0:
            water = 0
        elif water >= m:
            water = m
    print(water)

测试结果如下:

想减少循环次数我觉得可以通过求t1和t2的最小公倍数,在最小公倍数时间内水池蓄水量,然后t // 最小公倍数时间 * 期间蓄水量,然后再加余数时间的蓄水量。具体用java实现:

import java.util.*;
public class Main7 {
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int T=in.nextInt();
        int m,t,m1,t1,m2,t2;
        int p1,p2;//标志给水放水状态
        int vlo;

        while(T>0){
            --T;
            m=in.nextInt();
            t=in.nextInt();
            m1=in.nextInt();
            t1=in.nextInt();
            m2=in.nextInt();
            t2=in.nextInt();
            p1=p2=0;
            vlo=0;
            for(int i=0;i<t;i++){
                if(i%t1==0) p1=1-p1;
                if(i%t2==0) p2=1-p2;

                vlo=vlo+p1*m1-p2*m2;
                if(vlo<0)vlo=0;
                if(vlo>m)vlo=m;
            }
            System.out.println(vlo);
        }
    }
}

测试结果如下:

3、水平线 (1)、题目描述:

伞屉国是一个以太阳能为主要发电手段的国家,因此他们国家中有着非常多的太阳能基站,链接着的基站会组合成一个发电集群。但是不幸的是伞屉国不时会遭遇滔天的洪水,当洪水淹没基站时,基站只能停止发电,同时被迫断开与相邻基站的链接。你作为伞屉国的洪水观察员,有着这样的任务:在洪水到来时,计算出发电集群被洪水淹没后被拆分成了多少个集群。 由于远古的宇宙战争的原因,伞屉文明是一个二维世界里的文明,所以你可以这样理解发电基站的位置与他们的链接关系:给你一个一维数组a,长度为n,表示了n个基站的位置高度信息。数组的第i个元素a[i]表示第i个基站的海拔高度是a[i],而下标相邻的基站才相邻并且建立链接,即x号基站与x-1号基站、x+1号基站相邻。特别的,1号基站仅与2号相邻,而n号基站仅与n-1号基站相邻。当一场海拔高度为y的洪水到来时,海拔高度小于等于y的基站都会被认为需要停止发电,同时断开与相邻基站的链接。

(2)、输入描述:

每个输入数据包含一个测试点。 第一行为一个正整数n,表示发电基站的个数 (0 < n <= 200000) 接下来一行有n个空格隔开的数字,表示n个基站的海拔高度,第i个数字a[i]即为第i个基站的海拔高度,对于任意的i(1<=i<=n),有(0 <= a[i] < 2^31-1) 接下来一行有一个正整数q(0 < q <= 200000),表示接下来有q场洪水 接下来一行有q个整数,第j个整数y[j]表示第j场洪水的海拔为y[j],对于任意的j(1<=j<=n),有(-2^31 < y[j] < 2^31-1)

(3)、输出描述:

输出q行,每行一个整数,第j行的整数ans表示在第j场洪水中,发电基站会被分割成ans个集群。标准答案保证最后一个整数后也有换行。

(4)、示例1

输入 10 6 12 20 14 15 15 7 19 18 13 6 15 23 19 1 17 24 输出 2 0 1 1 2 0

(5)、解题思路

对问题进行离线处理,由小到大排序,再对节点由小到大扫过去更新答案,时间复杂度再 O(n + m)

import java.io.*;
import java.util.Scanner;
import java.lang.reflect.Array;
import java.util.*;
public class Main8 {
    public static void main(String[] args) {
        try {
            StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
            sc.nextToken();
            int n = (int)sc.nval;
            int lo[][] = new int[n][2];
            for (int i = 0; i < n; i++) {
                sc.nextToken();
                lo[i][0] = (int)sc.nval;
                lo[i][1] = i + 1;
            }
            sc.nextToken();
            int m = (int)sc.nval;

            int yan[][] = new int[m][2];
            for (int i = 0; i < m; i++) {
                sc.nextToken();
                yan[i][0] = (int)sc.nval;
                yan[i][1] = i;
            }

            Arrays.sort(lo, (o1, o2) -> o1[0] - o2[0]);
            Arrays.sort(yan, (o1, o2) -> o1[0] - o2[0]);
            int ans[] = new int[m];
            boolean vis[] = new boolean[n + 2];
            int kuai = 1;
            int j = 0;
            vis[0] = vis[n + 1] = true;
            PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));

            for (int i = 0; i < m; i++) {
                for (; j < n && lo[j][0] <= yan[i][0]; j++) {
                    vis[lo[j][1]] = true;
                    int tot = 0;
                    if (vis[lo[j][1] - 1]) tot++;
                    if (vis[lo[j][1] + 1]) tot++;
                    if (tot == 2) kuai--;
                    if (tot == 0) kuai++;

                }
                ans[yan[i][1]] = kuai;
            }
            for (int i = 0; i < m; i++) {
                out.println(ans[i]);
            }
            out.flush();
        }
        catch (Exception e){

        }
    }
}

测试结果如下:

其实可以用暴力法,用python将其实现

n1 = int(input())
x = list(input().split())
n2 = int(input())
y = list(input().split())
for i in range(n2):
    l1 = []
    answer = 0
    gaodu = int(y[i])
    for j in range(n1):
        if int(x[j]) > gaodu:
                if j == n1-1:
                    answer += 1
                elif int(x[j+1])<= gaodu:
                    answer +=1
    print(answer)

测试结果如下

等到两个数组后分别排序,基本逻辑就是海啸从低到高,电站海拔也从低到高,被低的海啸淹没的电站也一定被高的海啸淹没, 初始集群为1,没当一个电站淹没时,若左右均已淹没则集群数减一,左右均未被淹没时集群数加一,有一边被淹没时集群数不变。用Python实现如下:

enb = int(input())
a_alti = [int(i) for i in input().split(" ")]
hx_t = int(input())
hx_h = [int(i) for i in input().split(" ")]
rsp_a = list(range(0, enb + 2))
rsp_a[0] = -1
rsp_a[enb + 1] = -1
hx_new_index = [index for index, value in sorted(enumerate(hx_h), key=lambda h: h[1])]
a_new_index = [index for index, value in sorted(enumerate(a_alti), key=lambda h: h[1])]
cluster_num = [0] * hx_t
k = 1
for i in range(hx_t):
    new_cluster = 0
    while k <= enb and a_alti[a_new_index[k-1]] <= hx_h[hx_new_index[i]]:
        if rsp_a[a_new_index[k-1]] == -1 and rsp_a[a_new_index[k-1]+2] == -1:
            new_cluster = new_cluster - 1
        elif rsp_a[a_new_index[k-1]] != -1 and rsp_a[a_new_index[k-1]+2] != -1:
            new_cluster = new_cluster + 1
        rsp_a[a_new_index[k-1]+1] = -1
        k = k + 1
    if i == 0:
        cluster_num[hx_new_index[i]] = 1 + new_cluster
    else:
        cluster_num[hx_new_index[i]] = cluster_num[hx_new_index[i - 1]] + new_cluster
for cn in cluster_num:
    print(cn)

测试结果如图所示:

总结

  本文针对本人这几天的笔试做了一个总结,一方面是为了方便自己以后笔试的复习,另外也是给大家再次面试百度的测试岗位的时候提供复习方向以及思路解答。从上面的几家大公司笔试题发现,考察的都是数据结构相关的具体应用,这与剑指offer和leetcode有很大的区别,需要我们在刷题的时候要融会贯通,其实考察更多的是动态规划。于是,我们在准备的时候,首先就应该夯实基础,只有这样才能在众多的笔试者中脱颖而出。最后希望大家不断进步,都能尽早拿到自己比较满意的offer!!!!继续加油,未来可期!!!!