ACM风格输入


我不会看不懂,就是读不懂题,不知道怎么正确的读入文件中的输入。

题目给出

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; // 返回跨区小和
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值