Java学习手册:贝壳找房2020校招——移动端工程师试卷

本文精选了四个编程挑战题目,包括寻找最小绝对值差的数字对、求解最长严格上升子序列、提高卫生检查分数及调整请求队列负荷。通过详细解析,展示了解决算法问题的技巧和策略。

一、计算绝对值

题目描述:

给出n个正整数,要求找出相邻两个数字中差的绝对值最小的一对数字,如果有差的绝对值相同的,则输出最前面的一对数。2<n<=100,正整数都在10^16范围内。

输入:

输入包含2行,第一行为n,第二行是n个用空格分隔的正整数。

输出:

输出包含一行两个正整数,要求按照原来的顺序输出。

样例输入:

9
1 3 4 7 2 6 5 12 32

样例输出:

3 4

程序如下:(AC18%)
package test;

import java.util.Scanner;

public class Test4 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String one = sc.nextLine();
		String two = sc.nextLine();
		String[] t = two.split(" "); 
		int n = Integer.parseInt(one);
		int[] a = new int[n];
		for(int i=0;i<n;i++) {
			a[i] = Integer.parseInt(t[i]);
		}
		int[] b = new int[n-1];
		for(int i=0;i<n-1;i++) {
			b[i] = Math.abs(a[i]-a[i+1]);
		}
		int count = Integer.MAX_VALUE;
		int flag = 0;
		for(int i=0;i<n-1;i++) {
			if(b[i]<count) {
				count = b[i];
				flag = i;
			}
		}
		System.out.println(a[flag]+" "+a[flag+1]);
	}
}

看了牛客讨论区后,发现问题出在数据类型选择上,题目要求最大在10^16范围,应选用Long Long(C语言)、BigInteger(Java语言)。

二、月光宝盒的密码

题目描述:

小希偶然得到了传说中的月光宝盒,然而打开月光宝盒需要一串密码。虽然小希并不知道密码具体是什么。但是月光宝盒说明书上有着一个长度为n(2<=N<=50000)的序列a(-10 ^9 <= a[i] <= 10 ^9)的范围内。下面写着一句话,密码是这个序列的最长的严格上升子序列的长度(严格上升子序列是指,子序列的元素是严格递增的,例如:[5,1,6,2,4]的最长严格上升子序列为[1,2,4]),请你帮小希找打这个密码。

输入:

第1行:1个数N,N为序列的长度(2<=N<=50000)
第2到N+1行:每行1个数,对应序列的元素(-10 ^9 <= a[i] <= 10 ^9)

输出:

一个正整数表示严格最长上升子序列的长度

样例输入:

8
5
1
6
8
2
4
5
10

样例输出:

5

程序如下:(AC82%)
package test;

import java.util.Scanner;

public class Test1 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int[] a = new int[n];
		int count = 0;
		while(sc.hasNext()) {
			int num = sc.nextInt();
			a[count] = num;
			count++;
			if(count >= n) {
				break;
			}
		}
		//记录上升序列的长度,dp[i]表示以a[i]结尾的子序列的最大长度
		int[] dp = new int[n];
		//记录dp数组中的最大值
		int result = 0;
		//按顺序计算dp值
		for(int i=0;i<n;i++) {
			dp[i] = 1;
			for(int j=0;j<i;j++) {
				if(a[i]>a[j] && dp[j]+1 > dp[i]) {
					dp[i] = dp[j] + 1; 
				}
			}
			result = Math.max(result, dp[i]);
		}
		System.out.println(result);
		sc.close();
	}
}
思路:利用动态规划来降低复杂度。

令dp[i]表示以a[i]结尾的最长上升子序列的长度,对a[i]来说有两种可能:
1)如果在i之前存在比a[i]小的数a[j](j<i),并且dp[j]+1>dp[i](即把a[i]放到以a[j]结尾的子序列之后其长度大于当前以a[i]结尾的子序列的长度),那么就把a[i]放到之前以a[j]结尾的子序列之后,并令其长度+1(即dp[i] = dp[j]+1)。
2)如果a[i]之前的所有数都比它大,那么只能a[i]自身成一个子序列,其长度为1。

三、检查卫生

题目描述:

一条直线上有n个教室,每个教室有一个当前的整洁度,第i个教室的整洁度为ai。有m个老师会来检查这n个教室的卫生情况,第i个老师抽查区间[Li,Ri]中的所有教室即第Li个教室,第Li+1个教室,一直到第Ri个教室,他们打分就是这个区间中所有教室的整洁度之和。而本次检查的最终总分就是这m个老师打分之和。检查马上就要开始了,你现在还可以打扫一间教室,打扫可以使得这间教室的整洁度再加1,请你选一间教室,使得最终检查的总得分最高!

输入:

第一行两个整数n,m(1<=n<=100000)
接下来一行n个整数a1,a2,…,an(0<=ai<=100)
最后输入m行,每行两个整数Li,Ri,表示每个老师抽查的区间(1<=Li<=Ri<=n)

输出:

输出一个数,最高得分。

样例输入:

4 3
1 2 3 4
1 4
2 4
3 4

样例输出:

29

提示:

测试样例中,打扫最后一个教室即可得到答案。

程序如下:

(未做,后续完善)

四、特殊的测试

题目描述:

小C在做一种特殊的服务器负载测试,对于一个请求队列中的请求,每一个请求都有一个负载值,为了保证服务器稳定,请求队列中的请求符合必须按照先递增后递减的规律(仅递增,仅递减也可以),比如[1,2,8,4,3],[1,3,5]和[10]这些是满足规律的,还有一些不满足的,比如[1,2,2,1],[2,1,2]和[10,10],现在给你一个请求队列,你可以对请求的负荷值进行增加,要求你调整队列中请求的负荷值,使数组满足条件。最后输出使队列满足条件最小的增加总和。

输入:

输入有两行,第一行是N(1<=n<=5000),代表请求队列的请求数量。
第二行有N个数字a1,a2,…,an(1<=ai<=10^9)。Ai是第i个请求的负荷值。

输出:

输出这个最小增加总和

样例输入:

5
1 4 3 2 5

输出:

6

提示:

样例解释:此时合法队列为[1,4,3,2,5],最小增加和为6。

程序如下:(AC64%)
package test;

import java.util.Scanner;

public class Test2 {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String first = sc.nextLine();
		String second = sc.nextLine();
		String[] sec = second.split(" ");
		int n = Integer.parseInt(first);
		int[] a = new int[n];
		for(int i=0;i<n;i++) {
			a[i] = Integer.parseInt(sec[i]);
		}
		int start = 0;
		int end = n-1;
		int min = 0;
		while(start < end && start+1 <= end && end-1 >= 0) {
			if(a[start]<a[start+1]) {
				start++;
			}
			if(a[end]<a[end-1]) {
				end--;
			}
			//找出需要处理的数据
			if(a[start]>a[end]) {
				for(int i=end-1;i>start;i--) {
					min += a[i+1]-a[i]+1;
					a[i] = a[i+1] + 1;
				}
			}else {
				for(int i=start+1;i<end;i++) {
					min += a[i-1]-a[i]+1;
					a[i] = a[i-1]+1;
				}
			}
		}
		System.out.println(min);
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值