我不会看不懂,就是读不懂题,不知道怎么正确的读入文件中的输入。
题目给出
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 注意 while 处理多个 case
int a = in.nextInt();
int b = in.nextInt();
System.out.println(a + b);
}
}
}
我写的
import java.io.*;
/**
* @Author: ggdpzhk
* @CreateTime: 2025-06-18
*/
public class _022 {
public static int MAX_N=100001;
public static int[] arr = new int[MAX_N];
public static int[] help = new int[MAX_N];
public static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
n = (int) in.nval;
for (int i = 0; i < n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
out.println(smallSum(0, n - 1));
}
out.flush();
out.close();
br.close();
}
//返回值类型是long,结果较大可能会越界
public static long smallSum(int l,int r){
//base case:左右边界相等时,即只有一个数,不会产生小和
if(l == r){
return 0;
}
//接下来就开始递归调用
int m = l + ((r-l) >> 1);
return smallSum(l,m) + smallSum(m+1,r)+merge(l,m,r);
}
public static long merge(int l,int m,int r){
//先算小和 ,然后有序
long ans = 0;
for(int i = l,j = m+1 ,sum = 0;j <= r;j++){
while (i <= m && arr[i] <= arr[j]){
sum += arr[i++];
}
ans += sum;
}
//先排序在return,现在return了,就直接终止了
int i = l;//计算help加入到哪里了
int a = l;
int b = m+1;
while(a<=m && b<=r){
help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++];
}
while(a <=m ){
help[i++] = arr[a++];
}
while(b <= r){
help[i++] = arr[b++];
}
//刷回原数组
for (i = l ;i <= r;i++){
arr[i] = help[i];
}
return ans;
}
}
但是拿我的提交了是能运行的
按照题目改
下面这个也是能运行的
import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static int MAX_N = 100001;
public static int[] arr = new int[MAX_N];
public static int[] help = new int[MAX_N];
public static int n;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 注意 hasNext 和 hasNextLine 的区别
while (in.hasNextInt()) { // 处理多个测试用例
n = in.nextInt(); // 读取数组长度
for (int i = 0; i < n; i++) {
arr[i] = in.nextInt(); // 读取数组元素
}
System.out.println(smallSum(0, n - 1)); // 计算并输出小和
}
}
// 计算小和:分治 + 归并
public static long smallSum(int l, int r) {
if (l == r) {
return 0; // 单个元素无小和
}
int m = l + ((r - l) >> 1); // 中点
return smallSum(l, m) + smallSum(m + 1, r) + merge(l, m, r); // 左小和 + 右小和 + 跨区小和
}
// 归并排序并计算跨区小和
public static long merge(int l, int m, int r) {
long ans = 0; // 跨区小和
// 计算左边比右边小的数的和
for (int i = l, j = m + 1, sum = 0; j <= r; j++) {
while (i <= m && arr[i] <= arr[j]) {
sum += arr[i++]; // 累加左边比 arr[j] 小的数
}
ans += sum; // 累加到总小和
}
// 归并排序
int i = l; // help 数组的起始位置
int a = l; // 左半部分起始
int b = m + 1; // 右半部分起始
while (a <= m && b <= r) {
help[i++] = arr[a] <= arr[b] ? arr[a++] : arr[b++]; // 按升序合并
}
while (a <= m) {
help[i++] = arr[a++]; // 剩余左半部分
}
while (b <= r) {
help[i++] = arr[b++]; // 剩余右半部分
}
// 刷回原数组
for (i = l; i <= r; i++) {
arr[i] = help[i];
}
return ans; // 返回跨区小和
}
}