标签:不用 string 解法 data 暴力求解 队列 问题 实现 描述
第一题
题目描述:
给定一个正整数组a,返回一个新的数组sums,满足sums[i]的值为正整数组a中比a[i]小的数字之和;如果不存在比a[i]小的数字,则sums[i]为0。已知数组a中元素最大值不超过100000,数组长度不超过10000,数组元素允许重复。
输入:
第一行为整数n,表示数组的长度。
接下来的n行数字表示数组里的元素。
输出:
正整数数组sums,使得sums长度与a长度相同。
输入样例:
4
5
4
2
9
输出样例:
6
2
0
11
第二题
题目描述:
给定一个圆,圆心在原点。给定圆上的一组点a[i](i = 1, 2, …, n),各点互不重复,且用x轴正方向逆时针转至与该点所在半径重合时所转角度的100倍(整数)表示,取值范围是[0, 36000)。我们可以从这组点中任选三点组成一个三角形。请问最多可以组成多少个钝角三角形?
输入:
第一行为一个正整数, n为点的个数。n <= 1000。
接下来n行,每一行有一个整数,每个数表示在圆边上的一个点。
输出:
任选三点时,可以组成的钝角三角形的数量。
输入样例甲:
4
0
10000
12000
18000
输出样例甲:
2
输入样例乙:
4
9000
0
27000
18000
输出样例乙:
0
第三题
题目描述:
建造房子是一项复杂的工程。施工队的设计师小张将造房子分成了m个任务,任务标号为1到m,每个工人一天能完成一个任务,任务之间可能有依赖。施工队里有n个工人,每一天,工人们依次从当前没有依赖的任务中选择标号最小的任务去做。问房子需要多少天建成?
输入:
第一行为三个整数:m,n,k。
其中:m为任务个数,n为工人个数。
1 <= m
n <= 2147483647
0 <= k <= 2147483647
接下来有k行,每一行有两个数字:i,j。表示标号为i的任务依赖于标号为j的任务。
其中:
1 <= i
j <= m
且 (i,j) 的组合不会重复出现
输出:
如果房子能建成,输出一个整数,表示需要花多少天。
如果房子不能建成,输出E。
输入样例甲:
6 2 5
2 1
3 1
5 2
5 3
6 5
输出样例甲:
4
输入样例乙:
7 2 6
3 1
2 1
5 4
6 4
7 6
4 7
输出样例乙:
E
第四题
题目描述:
要砌一面合适的墙有严格的要求:
1. 墙上不得有任何空隙;
2. 为了保证墙足够结实,墙绝对不能被垂直地切分成两面墙(反例如下图所示);
3. 所有的砖块只能水平地放置,即长边必须同水平面平行;
小明是一名砌墙工人,现在小明拥有四种尺寸的砖块,分别是1x1, 1x2, 1x3, 1x4,如果他需要砌一面尺寸为NxM(N表示高度,M表示宽度)的墙,并需要满足以上三个要求,请问一共可以有多少方案?
输入:
第一行为输入的数据组数T。
接下来有T行,每一行有两个数字:N和M,N表示高度,M表示宽度。
输出:
输出为T行结果,表示成功的砌墙方案数。
输入样例:
4
2 2
3 2
2 3
4 4
输出样例:
3
7
9
3375
Hulu往届校招编程测试解析
第一题
真题解析:
解法一:暴力求解。即两层遍历,内层遍历找出数组中比当前数字小的数字并求和。时间复杂度为O(n^2)。
解法二:由解法一,内层遍历的复杂度是O(n),根据题意是求比某元素小的元素之和,可以联想到对数组进行排序,那么“求原数组中小于某元素数字之和”的问题就转化为了“计算排序后数组中该元素所在位置前面的数字之和”的问题。并且可以观察到,对于排序后的数组b及小于b[i]的元素之和sum[i],有sum[i] = b[i-1] + sum[i-1],可知可以通过复用前面的计算结果进而提升性能。此题另外需要注意的是,要考虑数组中有重复的情况。优化后的算法时间复杂度为O(nlgn),空间复杂度为O(n)。
第二题
真题解析:
这道题最根本的问题是,给定三个点后,如何判断组成的是钝角三角形。
最直观的方式是,在半个圆的角度之内的任意三点组成的三角形都是钝角三角形。所以暴力解法的话可以对所有点循环一遍,检测是否是钝角三角形,时间复杂度为O(n^3)。
既然组成钝角三角形的三个点一定在180度内,那么也可以先行排序。根据点的顺时针方向去对每个点寻找自己作为顺时针起点时,180度内有多少个钝角三角形。假设顺时针180度内还有n个点,则该点作为顺时针起点的钝角三角形数量为C(n, 2)。在排序后一遍O(n)即可算出来,总的时间复杂度为O(nlogn)。
第三题
真题解析:
这道题目的场景十分常见,题目可以描述为实现一个可以调度相互依赖的、可并行执行的任务的系统。为了简化题目描述和实现,出题人加了两个约束:
1. 每个任务的执行时间一样;
2. 每一天总是从最小的任务开始挑选。
实现的方法比较直观,就是维护一个可执行任务的集合,每个循环开始的时候从最小的任务开始执行,再把新出现的没有依赖的任务加进去。
需要注意的地方有几点:
1. 某一天执行完所有任务后,再把新的任务加进去,不要每执行完一个就添加;
2. 这个可执行任务的集合最好用堆或者优先队列,这样不用每一天都排序;
3. 需要理解房子不能建成,是因为有循环依赖。
第四题
真题解析:
首先以输入N=3、M=2为例,每层可以有一个1*2或由两个1*1的砖拼成,那么总共可能的拼墙方案有2^3=8种,其中,不合法的拼墙方案是每层都由两个1*1的砖拼成,所以答案是8-1=7种。
对于其他的输入,可以用类似的思路,先求出所有的可能方案,然后减去所有不合法的方案,就是最终的答案。
为求所有的可能方案,需求出每层都多少种拼墙方案,这是个简单的dp,row[i]表示用四种长度的砖拼成长度为i的一层有多少种方案,递推方程是row[i] = row[i-1] + row[i-2] + row[i-3] + row[i-4]。总的解决方案就是any[i] = row[M]^N。
为求所有不合法的方案,需要遍历墙会在哪个地方(i)第一次可以被切分,被切分的左边是所有合法的墙,右边是所有可能的墙,所以转换成另一个dp。solid[i]表示一面i*N的墙有多少种合法方案,递推方程是solid[i] = sum(solid[j]*any[i-j])),j在1到i之间。solid[M]就是最终的解。
除此之外,还需要考虑大数据的问题,在计算的过程中都需要注意取模,注意好细节就可以了。
标签:不用 string 解法 data 暴力求解 队列 问题 实现 描述
原文地址:https://www.cnblogs.com/vector11248/p/11432345.html