算法笔试处理输入输出
BufferReader
普通读
java
package class019;
// 展示acm风格的测试方式
// 子矩阵的最大累加和问题,不要求会解题思路,后面的课会讲
// 每一组测试都给定数据规模
// 任何空间都提前生成好,一律都是静态空间,然后自己去复用,推荐这种方式
// 测试链接 : https://www.nowcoder.com/practice/cb82a97dcd0d48a7b1f4ee917e2c0409?
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Code03_StaticSpace {
// 题目给定的行的最大数据量
public static int MAXN = 201;
// 题目给定的列的最大数据量
public static int MAXM = 201;
// 申请这么大的矩阵空间,一定够用了
// 静态的空间,不停复用
public static int[][] mat = new int[MAXN][MAXM];
// 需要的所有辅助空间也提前生成
// 静态的空间,不停复用
public static int[] arr = new int[MAXM];
// 当前测试数据行的数量是 n
// 当前测试数据列的数量是 m
// 这两个变量可以把代码运行的边界规定下来
public static int n, m;
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;
in.nextToken();
m = (int) in.nval;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
in.nextToken();
mat[i][j] = (int) in.nval;
}
}
out.println(maxSumSubmatrix());
}
out.flush();
br.close();
out.close();
}
// 求子矩阵的最大累加和,后面的课会讲
public static int maxSumSubmatrix() {
int max = Integer.MIN_VALUE;
for (int i = 0; i < n; i++) {
// 因为之前的过程可能用过辅助数组
// 为了让之前结果不干扰到这次运行,需要自己清空辅助数组需要用到的部分
Arrays.fill(arr, 0, m, 0);
for (int j = i; j < n; j++) {
for (int k = 0; k < m; k++) {
arr[k] += mat[j][k];
}
max = Math.max(max, maxSumSubarray());
}
}
return max;
}
// 求子数组的最大累加和,后面的课会讲
public static int maxSumSubarray() {
int max = Integer.MIN_VALUE;
int cur = 0;
for (int i = 0; i < m; i++) {
cur += arr[i];
max = Math.max(max, cur);
cur = cur < 0 ? 0 : cur;
}
return max;
}
}按行读
适用读取字符串
java
package class019;
// 展示acm风格的测试方式
// 测试链接 : https://www.nowcoder.com/exam/test/70070648/detail?pid=27976983
// 其中,7.A+B(7),就是一个没有给定数据规模,只能按行读数据的例子
// 此时需要自己切分出数据来计算
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code,提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
public class Code04_ReadByLine {
public static String line;
public static String[] parts;
public static int sum;
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while ((line = in.readLine()) != null) {
parts = line.split(" ");
sum = 0;
for (String num : parts) {
sum += Integer.valueOf(num);
}
out.println(sum);
}
out.flush();
in.close();
out.close();
}
}Kattio
java
package class019;
// 本文件课上没有讲,介绍一下Kattio类的使用
// 某些题目的输入,使用StreamTokenizer就是无法正确读入
// 那么可以使用本文件提供的Kattio类
// 比如,就是需要依次读取一个一个的字符串进行处理
// 再比如,StreamTokenizer读取:不溢出、但是很大的long类型数字时,可能会读入错误
// 再比如,StreamTokenizer读取:科学计数法表达的double类型数字时,可能会读入错误
// 如果使用Kattio进行读取,就没有这些问题
// 可以直接运行本文件的main函数,根据提示输入给定的数字,能清晰的看到这一点
// 那么可不可以放弃StreamTokenizer,以后都用Kattio呢?
// 不行!因为StreamTokenizer的效率还是比Kattio好!
// 只有在StreamTokenizer无法正确读取的情况下,才考虑使用Kattio类
// 其他语言中一定有对等的概念,不是java的同学,请自行搞定
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.StringTokenizer;
public class Code05_Kattio {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
System.out.println("请输入 : 131237128371723187");
System.out.println("并按回车");
in.nextToken();
long long1 = (long) in.nval;
System.out.println("StreamTokenizer读取到的数字 : ");
System.out.println(long1);
System.out.println();
System.out.println("请输入 : 5.6920E+0001");
System.out.println("并按回车");
in.nextToken();
double double1 = in.nval;
System.out.println("StreamTokenizer读取到的数字 : ");
System.out.println(double1);
System.out.println("============================");
Kattio io = new Kattio();
System.out.println("请输入 : 131237128371723187");
System.out.println("并按回车");
long long2 = io.nextLong();
System.out.println("Kattio读取到的数字 : ");
System.out.println(long2);
System.out.println();
System.out.println("请输入 : 5.6920E+0001");
System.out.println("并按回车");
double double2 = io.nextDouble();
System.out.println("Kattio读取到的数字 : ");
System.out.println(double2);
io.close();
}
// 如何使用Kattio的简单示例
// 可以找个一些具体题目试一试
// 这里就是罗列了一下
public static void show() {
Kattio io = new Kattio(); // 自动接入输入输出流
io.next(); // 读取下一个字符串,注意不是整行,是以空格或回车分割的字符串,一个一个读取
io.nextInt(); // 读取下一个int
io.nextDouble(); // 读取下一个double
io.nextLong(); // 读取下一个long
io.println("ans"); // 答案进入输出流
io.flush(); // 答案刷给后台
io.close(); // 关闭io
}
// Kattio类IO效率很好,但还是不如StreamTokenizer
// 只有StreamTokenizer无法正确处理时,才考虑使用这个类
// 参考链接 : https://oi-wiki.org/lang/java-pro/
public static class Kattio extends PrintWriter {
private BufferedReader r;
private StringTokenizer st;
public Kattio() {
this(System.in, System.out);
}
public Kattio(InputStream i, OutputStream o) {
super(o);
r = new BufferedReader(new InputStreamReader(i));
}
public Kattio(String intput, String output) throws IOException {
super(output);
r = new BufferedReader(new FileReader(intput));
}
public String next() {
try {
while (st == null || !st.hasMoreTokens())
st = new StringTokenizer(r.readLine());
return st.nextToken();
} catch (Exception e) {
}
return null;
}
public int nextInt() {
return Integer.parseInt(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public long nextLong() {
return Long.parseLong(next());
}
}
}FastReaderWriter
java
package class019;
// 本文件课上没有讲
// java同学可以使用FastReader进行快读,可以使用FastWriter进行快写,速度是很快的
// 如何使用可以参考main函数
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.InputMismatchException;
public class Code06_FastReaderWriter {
public static void main(String[] args) {
FastReader reader = new FastReader(System.in);
FastWriter writer = new FastWriter(System.out);
System.out.println("输入一个字符:");
int cha = reader.readByte(); // reader会读到字符的ASCII码
System.out.println("输入一个int类型的数字:");
int num1 = reader.readInt(); // reader会读到该数字
System.out.println("输入一个long类型的数字:");
long num2 = reader.readLong(); // reader会读到该数字
System.out.println("打印结果:");
writer.println(cha);
writer.println(num1);
writer.println(num2);
writer.close();// close方法包含flush,会把结果刷出去
}
// 快读
public static class FastReader {
InputStream is;
private byte[] inbuf = new byte[1024];
public int lenbuf = 0;
public int ptrbuf = 0;
public FastReader(final InputStream is) {
this.is = is;
}
public int readByte() {
if (lenbuf == -1) {
throw new InputMismatchException();
}
if (ptrbuf >= lenbuf) {
ptrbuf = 0;
try {
lenbuf = is.read(inbuf);
} catch (IOException e) {
throw new InputMismatchException();
}
if (lenbuf <= 0) {
return -1;
}
}
return inbuf[ptrbuf++];
}
public int readInt() {
return (int) readLong();
}
public long readLong() {
long num = 0;
int b;
boolean minus = false;
while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
;
if (b == '-') {
minus = true;
b = readByte();
}
while (true) {
if (b >= '0' && b <= '9') {
num = num * 10 + (b - '0');
} else {
return minus ? -num : num;
}
b = readByte();
}
}
}
// 快写
public static class FastWriter {
private static final int BUF_SIZE = 1 << 13;
private final byte[] buf = new byte[BUF_SIZE];
private OutputStream out;
private Writer writer;
private int ptr = 0;
public FastWriter(Writer writer) {
this.writer = new BufferedWriter(writer);
out = new ByteArrayOutputStream();
}
public FastWriter(OutputStream os) {
this.out = os;
}
public FastWriter(String path) {
try {
this.out = new FileOutputStream(path);
} catch (FileNotFoundException e) {
throw new RuntimeException("FastWriter");
}
}
public FastWriter write(byte b) {
buf[ptr++] = b;
if (ptr == BUF_SIZE) {
innerflush();
}
return this;
}
public FastWriter write(String s) {
s.chars().forEach(c -> {
buf[ptr++] = (byte) c;
if (ptr == BUF_SIZE) {
innerflush();
}
});
return this;
}
private static int countDigits(long l) {
if (l >= 1000000000000000000L) {
return 19;
}
if (l >= 100000000000000000L) {
return 18;
}
if (l >= 10000000000000000L) {
return 17;
}
if (l >= 1000000000000000L) {
return 16;
}
if (l >= 100000000000000L) {
return 15;
}
if (l >= 10000000000000L) {
return 14;
}
if (l >= 1000000000000L) {
return 13;
}
if (l >= 100000000000L) {
return 12;
}
if (l >= 10000000000L) {
return 11;
}
if (l >= 1000000000L) {
return 10;
}
if (l >= 100000000L) {
return 9;
}
if (l >= 10000000L) {
return 8;
}
if (l >= 1000000L) {
return 7;
}
if (l >= 100000L) {
return 6;
}
if (l >= 10000L) {
return 5;
}
if (l >= 1000L) {
return 4;
}
if (l >= 100L) {
return 3;
}
if (l >= 10L) {
return 2;
}
return 1;
}
public FastWriter write(long x) {
if (x == Long.MIN_VALUE) {
return write("" + x);
}
if (ptr + 21 >= BUF_SIZE) {
innerflush();
}
if (x < 0) {
write((byte) '-');
x = -x;
}
int d = countDigits(x);
for (int i = ptr + d - 1; i >= ptr; i--) {
buf[i] = (byte) ('0' + x % 10);
x /= 10;
}
ptr += d;
return this;
}
public FastWriter writeln(long x) {
return write(x).writeln();
}
public FastWriter writeln() {
return write((byte) '\n');
}
private void innerflush() {
try {
out.write(buf, 0, ptr);
ptr = 0;
} catch (IOException e) {
throw new RuntimeException("innerflush");
}
}
public void flush() {
innerflush();
try {
if (writer != null) {
writer.write(((ByteArrayOutputStream) out).toString());
out = new ByteArrayOutputStream();
writer.flush();
} else {
out.flush();
}
} catch (IOException e) {
throw new RuntimeException("flush");
}
}
public FastWriter println(long x) {
return writeln(x);
}
public void close() {
flush();
try {
out.close();
} catch (Exception e) {
}
}
}
}全局静态空间
建议使用全局静态空间,递归返回后,在下次递归时空间可以复用,不用每次都去 new 一个空间,效率低
