最近在准备CCF,做到这道题的时候半天看不懂题,没办法去学习了大佬的思路(CSDN日沉云起),自己按照他给的思路自己用Java实现了一个,上传之后结果超时60分,实在想不出怎么优化,在论坛找到了一个输入输出加速优化的方法,特记录下来。
这是优化原地址。https://bbs.csdn.net/topics/395020645
IO优化
// 输出优化
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
这一步主要是输出优化,加快输出的速度,不过在过程中调用 out.print() 并不会输出,而是写到缓冲区,须要在全部完成刷新缓冲区,便会将所有数据输出出来。
out.flush();
接下来是输入优化,在主类中嵌入一个输入器 InputReader 类,主要使用BufferReader逐行读取数据,并实现 nextInt() 等方法,其中Buffer读到的整行字符串用StringTokenizer类对象来存储,方便于分割。整个过程相当于将原有的输入类进行再封装,实现一个自己的输入器,代码如下:
static class InputReader {
private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private static StringTokenizer tokenizer = null;
static String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return tokenizer.nextToken();
}
static int nextInt() {
return Integer.parseInt(next());
}
static long nextLong() {
return Long.parseLong(next());
}
}
通过这两个IO优化之后原本运行超时(超过5s),直接100分3s左右通过了,由衷感谢两位大佬。
完整代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;
//ccf测试题
class Commodity implements Comparable<Commodity> {
long id;// 编号
long score;// 分数
public Commodity(long id, long score) {
// TODO Auto-generated constructor stub
this.id = id;
this.score = score;
}
@Override
public int compareTo(Commodity o) {
// TODO Auto-generated method stub
if (this.score != o.score) {
if (this.score < o.score) {
return 1;
} else {
return -1;
}
} else {
if (this.id < o.id) {
return -1;
} else if (this.id == o.id) {
return 0;
} else {
return 1;
}
}
}
}
public class Main {
// 输出优化
static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) {
final long mul = (long) 1e9;
int m = InputReader.nextInt(), n = InputReader.nextInt();
TreeSet<Commodity> set = new TreeSet<Commodity>();
HashMap<Long, Commodity> map = new HashMap();// 通过id找到对应id的类对象
for (int i = 0; i < n; i++) {
long id = InputReader.nextInt();
long score = InputReader.nextInt();
for (int j = 0; j < m; j++) {
long a = j * mul + id;
Commodity temp = new Commodity(a, score);
set.add(temp);
map.put(a, temp);
}
}
int opNum = InputReader.nextInt();// 操作数目
for (int i = 0; i < opNum; i++) {
int num = InputReader.nextInt();// 符号
if (num == 1) {// 添加商品
int type = InputReader.nextInt();// type类商品
long id = InputReader.nextLong();
long score = InputReader.nextLong();
long a = type * mul + id;
Commodity temp = new Commodity(a, score);
set.add(temp);
map.put(a, temp);
} else if (num == 2) {// 删除商品
int type = InputReader.nextInt();// type类商品
long id = InputReader.nextLong();
long a = type * mul + id;
set.remove(map.get(a));
map.remove(a);
} else if (num == 3) {// 挑选商品
Vector<Integer> k = new Vector<Integer>();
int K = InputReader.nextInt();
for (int j = 0; j < m; j++) {// 存储k_i的值
k.add(InputReader.nextInt());
}
Vector<Long>[] ans = new Vector[m];
// 遍历set集合
for (int index = 0; index < m; index++) {
ans[index] = new Vector<Long>();
}
for (Commodity a : set) {
int type = (int) (a.id / mul);
long com = a.id % mul;
if (k.get(type) == 0) {
continue;
}
ans[type].add(com);
k.set(type, k.get(type) - 1);
K--;
if (K == 0)
break;
}
// 输出
for (int j = 0; j < m; j++) {
if (ans[j].size() == 0) {
out.print(-1);
} else {
for (int z = 0; z < ans[j].size(); z++) {
out.print(ans[j].get(z) + " ");
}
}
out.print('\n');
}
} else {
System.out.println("输入有误!非法操作!");
System.exit(1);
}
}
// 全部计算结束后刷新缓冲区来输出数据
out.flush();
out.close();
}
// 输入优化
static class InputReader {
private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
private static StringTokenizer tokenizer = null;
static String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
e.printStackTrace();
}
}
return tokenizer.nextToken();
}
static int nextInt() {
return Integer.parseInt(next());
}
static long nextLong() {
return Long.parseLong(next());
}
}
}
网友评论