#25. 交通违法统计

内存限制:800 MiB 时间限制:10000 ms 输入文件:in 输出文件:out
题目类型:传统 评测方式:文本比较
上传者: pony

题目描述

交通部要统计下近期的违章数据,警察叔叔为了降低难度,已经给全国的车牌进行了int类型的自增id编码,有两个需求:

  1. 按id升序统计每辆车的违章次数。取所有违章id中间的那个。一共x辆车违章,就取第x/2个

  2. 统计违章最多的n个车主违章次数的平均值。如果出现并列,只取前n个。

输入格式

大端模式的byte文件,全按int读即可。 如00000001表示1,0000000a表示10,00bc4ff2表示12341234 。

第一个int表示记录的条数,第二个int表示题目中要求的n,后面的int表示发生违章的车辆id,乱序。

输出格式

两行结果,均为int

样例

输入:

如10 3 1 1 1 7 1 2 5 8 5 98877121

表示一共10条记录,求违章次数最多的3个车牌号违章次数的平均。发生违章的车辆依次是1,1,1,7,1,2,5,8,5,98877121

输出:

5

2

第一步的结果为

1,4;

2,1;

5,2;

7,1;

8,1;

98877121,1;

输出第三个id 5

1号车违章4次,5号车违章2次,2号1次,(7,8,98877121都是一次,并列的只取一个即可)5号2次 平均 (4+1+2)/3 = 2,取整即可

输出平均值2

import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
//示例代码,应该会比较慢吧,本题采用文件io接口,可以直接new File("in"),new File("out")这样调用
public class Main {
    public static void main(String[] args) throws Exception{
        RandomAccessFile fs = new RandomAccessFile("in", "r");
        FileChannel fc = fs.getChannel();
        MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
        IntBuffer intBuffer = buffer.asIntBuffer();
        PrintStream stream = new PrintStream("out");
        int size = intBuffer.get();
        int n = intBuffer.get();
        TreeMap<Integer, Integer> map = new TreeMap<>();
        for (int i = 0 ; i< size ; i++){
            int id = intBuffer.get();
            if (!map.containsKey(id)){
                map.put(id, 1);
            } else {
                map.put(id, map.get(id) + 1);
            }
        }
        int index = map.size() / 2;
        List<Integer> list = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : map.entrySet()){
            list.add(entry.getValue());
            if (--index == 0){
                stream.println(entry.getKey());
            }
        }
        Collections.sort(list);
        int sum = 0;
        for (int i = list.size() - 1;i> list.size() -n; i--){
            sum += list.get(i);
        }
        stream.println(sum/n);
        fc.close();
        stream.close();
    }
}

数据范围与提示

截止到2018年底我国机动车约2.4亿辆(这个是真是数据,即id的范围为0到2.4亿,小于2.4亿),闯红灯的车辆最多不超过5%(这个是这批数据)。 有些套牌的车辆没识别成功,比如京A88888被好多车套牌了,经常违章,导致数据里一辆车可能超过几十万条记录哟