【华为od】几何平均值最大子数组
写的很菜,没有多余的测试用例,不知道正确率怎么样,考试答过这道题的大佬,辛苦指教一下。
几何平均值最大子数组
知识点数组二分查找
时间限制:1s 空间限制:256MB 限定语言:不限
题目描述:
从一个长度为N的正数数组numbers中找出长度至少为L且几何平均值最大子数组,并输出其位置和大小。(K个数的几何平均值为K个数的乘积的K次方根)
若有多个子数组的几何平均值均为最大值,则输出长度最小的子数组。
若有多个长度相同的子数组的几何平均值均为最大值,则输出最前面的子数组。
输入描述:
第一行输入为N、L,N表示numbers的大小(1 <= N <= 100000),L表示子数组的最小长度(1 <= L <= N),
之后N行表示numbers中的N个数,每个一行(10-9 <= numbers[i] <= 109)。
输出描述:
输出子数组的位置(从0开始计数)和大小,中间用一个空格隔开。
补充说明:
用例保证除几何平均值为最大值的子数组外,其他子数组的几何平均值至少比最大值小最大值的10-10倍
示例1
输入:
3 2
2
2
3
输出:
1 2
说明:
长度至少为2的子数组共三个,分别是{2,2}、{2,3}、{2,2,3},其中{2,3}的几何平均值最大,故输出其位置1和长度2
示例2
输入:
10 2
0.2
0.1
0.2
0.2
0.2
0.1
0.2
0.2
0.2
0.2
输出:
2 2
说明:
有多个长度至少为2的子数组的几何平均值为0.2,其中长度最短的为2,也有多个,长度为2且几何平均值为0.2的子数组最前面的那个为从第二个数开始的两个0.2组成的子数组
public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextLine()) { String[] str = in.nextLine().split(" "); int N = Integer.valueOf(str[0]); int L = Integer.valueOf(str[1]); double[] arr = new double[N]; for (int i = 0; i < N; i++) { arr[i] = Double.valueOf(in.nextLine()); } double[][] map = new double[N-L+1][N+1]; for(int i = 0;i <= N-L;i++){ for (int j = i+L-1; j < N; j++) { BigDecimal sum = new BigDecimal(1); for (int k = i; k <=j ; k++) { BigDecimal kk = new BigDecimal(String.valueOf(arr[k])); sum = sum.multiply(kk); } map[i][j-i+1] = sum.doubleValue(); } } double[][] resultMap = new double[2][N+1]; for (int i =0 ; i <N+1 ;i++){ for (int j = 0; j < N-L+1; j++) { resultMap[0][i] = Math.max(resultMap[0][i],map[j][i]); } } double max = 0d; int x=0; for (int i = L-1; i < resultMap[0].length; i++) { resultMap[1][i] = Math.pow(resultMap[0][i],1d/i); BigDecimal b1 = new BigDecimal(resultMap[1][i]); BigDecimal b2 = new BigDecimal(max); if (b1.compareTo(b2) >0){ max = resultMap[1][i]; x = i; } } int y = 0; double maxy = 0; for (int i = 0; i < N-L+1; i++) { if (map[i][x] > maxy){ maxy = map[i][x]; y = i; } } System.out.println(y+" "+x); } } }