Kotlin 用于竞赛程序的一些tricks -- 1. 输入


Kotlin

kotlin 已经成为 ACM ICPC 正式的编程语言了

The programming languages of the ICPC World Finals are Java, Kotlin, Python and C/C++.
---- https://icpc.global/regionals/rules

然而博主不打竞赛.
总之就是一些个人使用的kotlin写竞赛代码的小tricks.
仅供参考娱乐

1. 输入

利用Java的BufferedReader

val reader = BufferedReader(InputStreamReader(System.`in`))

定义一个函数,把一整行字符串按空格分开.

fun readLineStrings() = reader.readLine().trim().split(' ')

定义一个读Int的函数方便使用,直接使用kotlin列表的map方法配合it简化的lambda.

fun readLineInts() = readLineStrings().map { it.toInt() }

这样面对大部分一行多个int的输入,可以利用kotlin的Destructuring declaration功能写出简洁漂亮的代码.
例如 一行有四个整数 n,m,s,t :

val (n, m, s, t) = readLineInts()

(kotlin就是漂亮啊)

在不卡输入速度的时候很好用,如果真卡输入速度,可以参考java的快读编写.

速度测试:

测试数据:
100,000,000 行,每行5个随机正整数(输入文件大小2.93G)
(第一行为两个正整数代表总行数和每行数字个数

测试代码:

C艹 C++ :

int lines, numsPerLine;
std::scanf("%d %d",&lines, &numsPerLine);
std::printf("%d\n",lines);
for(size_t i = 0; i < lines; ++i){
    int a,b,c,d,e;
    std::scanf("%d %d %d %d %d",&a,&b,&c,&d,&e);
}   

Kotlin:

import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.*

val reader = BufferedReader(InputStreamReader(System.`in`))
fun readLineStrings() = reader.readLine().trim().split(' ')
fun readLineInts() = readLineStrings().map { it.toInt() }

fun main() {
    val(lines,_) = readLineInts()
    println("$lines")
    for(i in 0 until lines){
        val(a,b,c,d,e) = readLineInts()
    }
}

测试结果

环境

系统 Mac OS 13.4
C++: clang 14  -Ofast
Kotlin:  Kotlin/JVM 1.9.0   Openjdk 17

结果:

C++: 20.80s
Kotlin: 23.97s

可以看出效率非常接近c++ scanf

未完待续…