HDOJ 2023 java语言 一种思路详解

如题
最近有点忙(JavaWeb好烦),所以有段时间没有做题了,正好发现了一道漏做的HDOJ第11页上的靠前的题目,做个分析整理来帮助我调整状态

HDOJ 2023原题链接

下面是java代码,里面有一些我调试时的无用代码,已经注释掉了。只是想抄的同学面向CV编程一波就可以走了,再下面是详解

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner kb = new Scanner(System.in);
        while (kb.hasNext()) {
            int n = kb.nextInt(), m = kb.nextInt();
            one(kb, n, m);
            System.out.println();
        }
    }

    public static void one(Scanner kb, int n, int m) {
        double[][] a = new double[n][m];
        int[] b = new int[n];
        int check = 0;
        for (int i = 0; i < n; i++) {       //录入分数
            for (int j = 0; j < m; j++) {
                a[i][j] = kb.nextDouble();
            }
        }
        for (int i = 0; i < n; i++) {
            double c = 0;
            b[i] = 1;
            for (int j = 0; j < m; j++) {
                c += a[i][j];
            }
            c /= m;
            if (check == 1) System.out.print(" ");
            System.out.printf("%.2f", c);
            check = 1;
        }
        System.out.println();
        check = 0;
        for (int i = 0; i < m; i++) {
            double c = 0;
            for (int j = 0; j < n; j++) {
                c += a[j][i];
            }
            c /= n;      //每科平均
            for (int j = 0; j < n; j++) {
                if (b[j] == 1 && c > a[j][i]) {
//                    System.out.println(c + " " + a[j][i] + " " + j + " " + i);
                    b[j] = 0;
                }
            }
            if (check == 1) System.out.print(" ");
            System.out.printf("%.2f", c);
            check = 1;
        }
        System.out.println();
        check = 0;
        for (int i : b) {
//            System.out.print(" =" + i);
            check += i;
        }
        System.out.println(check);
    }
}

下面我来慢慢的分析题目

首先是有多个测试实例,所以照惯例hasNext的判断必不可少,这也是HDOJ的特色吧

然后我们可以从题目中得知每个测试实例在第一行会有两个参数,分别是代表学生数量的 n 以及代表课程数量的 m ,我们可以简单的写出读入语句。

为了防止数据和题目描述不一致(曾经我还不太会写程序时暴力写一道忘了哪里的题目时总是WA,最后发现题目描述里的数据范围有误),我是动态生成不同大小的二维数组来进行操作。

 public static void main(String[] args) {
        Scanner kb = new Scanner(System.in);
        while (kb.hasNext()) {
            int n = kb.nextInt(), m = kb.nextInt();
            one(kb, n, m);
            System.out.println();
        }
    }

在java中,主函数main里面数组定义不可以用变量,所以我把n和m传入函数中。

是所以要把Scanner对象也传进去是因为有些OJ的java在创建一个Scanner对象之后,即使销毁此对象再传参到函数,函数里面再创Scanner对象就会报错。

double[][] a = new double[n][m];
int[] b = new int[n];
int check = 0;
for (int i = 0; i < n; i++) {       //录入分数
    for (int j = 0; j < m; j++) {
		a[i][j] = kb.nextDouble();
	}
}

在函数里我定义了一个二维数组a用来存储输入的信息,一个一维数组b来计算各科成绩均大于等于平均成绩的学生数量,为了节省时间(虽说感觉也不会TLE)我在某次循环时初始化数组b减少了循环的时间。

我们知道n个人,m科,如图

12n-1n
1
2
m-1
m

那么没科成绩平均数和单人成绩平均数就是一行/列的平均数,就可以简单的进行单行/单列的读取并输出,为了格式,我定义了一个int类型的check,用于判断这一行是否输出过。至于为什么用int类型而不用boolean类型,是因为check在后面会复用。

for (int i = 0; i < n; i++) {
            double c = 0;
            b[i] = 1;
            for (int j = 0; j < m; j++) {
                c += a[i][j];
            }
            c /= m;
            if (check == 1) System.out.print(" ");
            System.out.printf("%.2f", c);
            check = 1;
        }
        System.out.println();
        check = 0;
        for (int i = 0; i < m; i++) {
            double c = 0;
            for (int j = 0; j < n; j++) {
                c += a[j][i];
            }
            c /= n;      //每科平均
            for (int j = 0; j < n; j++) {
                if (b[j] == 1 && c > a[j][i]) {
//          System.out.println(c + " " + a[j][i] + " " + j + " " + i);
                    b[j] = 0;
                }
            }
            if (check == 1) System.out.print(" ");
            System.out.printf("%.2f", c);
            check = 1;
        }
        System.out.println();

你们可以看到在计算每科平均成绩的循环里我加上了如下代码

for (int j = 0; j < n; j++) {
    if (b[j] == 1 && c > a[j][i]) {
//      System.out.println(c + " " + a[j][i] + " " + j + " " + i);
        b[j] = 0;
    }
}

这代码用来及时判断并筛选掉有单科没有过的同学,先判断是否还没有被筛选掉,再判断是否单科没有过。

最后用一个foreach来循环,计算人数

check = 0;
for (int i : b) {
	check += i;
}
System.out.println(check);

看不懂foreach的同学看下面,下面代码可以代替foreach

for (int i = 0; i < n; i++) {
	check += i;
}

这就是一种HDOJ 2023的解法了

本文用于备忘和分享

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值