【发布时间】:2016-07-31 00:44:18
【问题描述】:
目标
我正在解决this 问题:
小女孩和最大和
小姑娘很喜欢数组查询的问题。
有一天,她遇到了一个众所周知的问题:你有一个 n 个元素的数组(数组的元素从索引开始 从 1);此外,有 q 个查询,每个查询由一对定义 整数 li, ri (1 ≤ li ≤ ri ≤ n)。您需要为每个查询找到 索引从 li 到 ri 的数组元素的总和。
小女孩觉得这个问题很无聊。她决定 在以某种方式回复查询之前重新排序数组元素 这使得查询回复的总和尽可能大。你的任务是 求这个最大和的值。
输入 第一行包含两个空格分隔的整数 n (1 ≤ n ≤ 2·105) 和 q (1 ≤ q ≤ 2·105) — 元素的数量 数组和查询的数量,对应。
下一行包含 n 个空格分隔的整数 ai (1 ≤ ai ≤ 2·105) — 数组元素。
以下 q 行中的每一行都包含两个空格分隔的整数 li 和 ri (1 ≤ li ≤ ri ≤ n) — 第 i 个查询。
输出 在一行中打印一个整数 - 的最大总和 数组元素重新排序后的查询回复。
对于测试 7(请参阅问题末尾的测试结果),输入是一个大小为 200,000 的数组,其中包含 200,000 个查询(具有 r 和 l 值)。
输入看起来像这样:
200000 200000
189622 189286 194361 184457 182376 183471 197548 184736 195806 ... 200,000 integers
188738 290041
33738 90041
122738 390041
... 200,000 line
您可以download a sample input file,也可以创建自己的示例输入。数字本身并不重要。
问题
我需要在不超过 2 秒的执行时间的情况下读取 600,000 行输入。问题是,它甚至没有在 2 秒内读取前 200,000 个输入。
如何加快我的代码在 2 秒内读取所有 600,000 个输入?
代码
这是我的第一次尝试:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int q = scanner.nextInt();
int[] array = new int[n];
for (int i=0; i<n; i++) {
array[i] = scanner.nextInt();
}
int[][] qArray = new int[q][2];
for (int i=0; i<q; i++) {
qArray[i][0] = scanner.nextInt();
qArray[i][1] = scanner.nextInt();
}
int[] index = new int[n];
Arrays.sort(array);
for (int i=0; i<q; i++) {
for (int j = qArray[i][0]-1; j<qArray[i][1]; j++) {
index[j]++;
}
}
Arrays.sort(index);
long sum =0;
for (int i = 0; i<n; i++) {
sum += index[i]*array[i];
}
System.out.println(sum);
}
}
这是我的第二次尝试:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String input = bufferedReader.readLine();
String[] SplitInput = input.split(" ");
int n = Integer.parseInt(SplitInput[0]);
int q = Integer.parseInt(SplitInput[1]);
String input2 = bufferedReader.readLine();
int[][] qArray = new int[q][2];
for (int i=0; i<q; i++) {
input = bufferedReader.readLine();
SplitInput = input.split(" ");
qArray[i][0] = Integer.parseInt(SplitInput[0]);
qArray[i][1] = Integer.parseInt(SplitInput[1]);
}
String[] SplitInput2 = input2.split(" ");
int[] array = new int[n];
for(int i=0; i<n; i++){
array[i] = Integer.parseInt(SplitInput2[i]);
}
int[] index = new int[n];
Arrays.sort(array);
for (int i=0; i<q; i++) {
for (int j = qArray[i][0]-1; j<qArray[i][1]; j++) {
index[j]++;
}
}
Arrays.sort(index);
long sum = 0;
for (int i=0; i<n; i++) {
sum += index[i]*array[i];
}
System.out.println(sum);
}
catch (NumberFormatException ex) {
System.out.println("Not a number !");
}
catch (IOException e) {
e.printStackTrace();
}
}
}
测试结果
尝试 1
7 时间:2000 毫秒,内存:20612 KB 判决:TIME_LIMIT_EXCEEDED
尝试 2
7 时间:2000 毫秒,内存:41340 KB 判决:TIME_LIMIT_EXCEEDED
【问题讨论】:
-
那么问题到底是什么?您是否通过分析器运行代码以查看时间?
-
您要求我们在我们无权访问的平台上、在我们无权访问的输入文件上使用包含明显错误的代码调试问题。既然你提到它,这个问题确实应该被杀死。
-
我无法访问完整的输入,但第一行是
200000 200000第二行是用空格分隔的 200,000 个整数,然后 200,000 行每行有两个用空格分隔的整数 -
啊,我明白你现在在问什么了。我认为大多数人(包括我一开始)都无法完全区分您在所有这些中提出的问题。我编辑了您的问题以使其更易于阅读,并再次重申您的问题(粗体)。我还提名你重新开放。我希望你能找到你的答案!在此期间,我建议您通过机器上的代码分析器运行您的代码。这将帮助您缩小性能瓶颈。
-
遗憾的是,chat.stackoverflow.com 上的人建议您将其发布到 CodeReview 而不是 StackOverflow 上
标签: java performance time execution-time