这里会在Codeforces上进行Kotlin语言的实践。
给出模板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 import java.util.*import kotlin.math.*fun readint () =readLine()!!.toInt()fun readll () =readLine()!!.toLong()fun readdb () =readLine()!!.toDouble()fun readstring () =readLine()!!fun readline_int () =(readLine()!!.split(" " ).map{it.toInt()}).toIntArray()fun readline_ll () =(readLine()!!.split(" " ).map{it.toLong()}).toLongArray()fun readline_db () =(readLine()!!.split(" " ).map{it.toDouble()}).toDoubleArray()fun main (args: Array <String >) {go()}data class pair (var fi:Int ,var se:Int ,var id:Int )val cmp: Comparator<pair> = Comparator{ a,b-> if (a.fi==b.fi) a.se.compareTo(b.se) else a.fi.compareTo(b.fi) } val INF=0x3f3f3f3f val LLINF=0x3f3f3f3f3f3f3f3fL val MAX=200000 +10 fun go () { }
正文 如何读入 由于 $java.util.Scanner$ 极其慢,所以放弃使用。
这里使用 $readLine()$ 方法,它返回一个可空类型 $String?$ ,迫使开发人员处理输入缺失的情况。
1 2 val n = readLine()?.toInt() val n: Int = readLine()!!.toInt()
竞技程序设计中的输入格式向来都是精确指定的,并且实际输入不能偏离问题陈述中的输入规范。这基本上就是空断言操作符 !!
的行为—— 它断言输入的字符串存在,如不存在则抛出异常。
1 2 3 4 5 val str = readLine()!! val n = readLine()!!.toInt() var (n, k) = readLine()!!.split(" " ).map{it.toInt()} val s = readLine()!!.split(" " ) var a = readLine()!!.split(" " ).map { it.toInt() }
可以定义为以下辅助函数,其他函数类似。
1 2 private fun readInt () = readLine()!!.toInt()private fun readInts () = readLine()!!.split(" " ).map { it.toInt() }
如何输出 方法 $print()$ 和 $println()$ 分别在内部调用 $System.out.print()$ 和$System.out.println()$ 。
1 2 var x = mutableListOf<Int >()println(x.joinToString(" " ))
数据存储 1 2 arr = ArrayList<Int >() 创建,可在括号内传一个Int 指定容量 var x = mutableListOf<Int >()
$HashMap$ 类使用 $Hash$ 表实现 $MutableMap$ 接口。 它以键和值对的形式存储数据,表示为 $HashMap <key,value>$。
1 2 3 4 5 hashMap.get (key) 返回指定键的值,若没有指定键,则返回null 。 hashMap.put(key, val ) 在指定键处添加新值并替换旧值。 hashMap.containsKey(key) 若key存在返回true ,否则返回false hashMap.containsValue(val ) 若val 存在返回true ,否则返回false hashMap.clear() 清除所有数据
基础语法 循环 1 2 3 4 for (i in 1. .5 ) print(i) for (i in 1 until 5 ) print(i) for (i in 5 downTo 1 ) print(i) for (i in 1. .5 step 2 ) print(i)
排序 1 2 3 4 a.sorted() a.sortedDescending() val lengthComparator = Comparator { str1: String, str2: String -> str1.length - str2.length } a.sortedWith(lengthComparator)
给定一个由 $n$ 个正整数组成的数组 $a$ ,保证其中只有一个元素是与其它元素不同的,输出这个元素的索引(从1开始)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 fun main (args: Array <String >) { var t: Int = readLine()!!.toInt() while (t-- > 0 ) { val n = readLine()!!.toInt() val a = readLine()!!.split(" " ).map { it.toInt() } val mp = HashMap<Int , Int >() for (i in a.indices) { if (!mp.containsKey(a[i])) mp.put(a[i], 0 ) mp.put(a[i], mp.get (a[i])!!+1 ) } var ans: Int = 0 for (i in a.indices) { if (mp.get (a[i]) == 1 ) { ans = i + 1 break } } println(ans) } }
定义一个操作为“重复”,它会将第 i 个字符重复 i 次,给定“重复“操作后的字符,求初始字符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 fun main (args: Array <String >) { val n: Int = readLine()!!.toInt() val s: String = readLine()!! var ans: String = "" var i = 0 var len = 0 while (i < n) { ans += s[i] len++ i += len } println(ans) }
$n$ 个数字,$n$ 为偶数,你要将他们分为 $\dfrac n2$ 个组,每组恰好两个数字。两个数字相同时才可以分到同一组,你可以每次对一个数进行+1操作,求能全部分组的最少操作次数。
思路 将这些数放到数轴上,会发现相近的两两连线即为最优方案,那么排序后做差求和即可。
代码 1 2 3 4 5 6 7 8 9 10 11 fun main (args: Array <String >) { val n: Int = readLine()!!.toInt() var a = readLine()!!.split(" " ).map {it.toInt()} var ans: Int = 0 a = a.sorted() for (i in 0. .n-1 step 2 ) { ans += a[i+1 ] - a[i] } println(ans) }
一个数组能否打乱顺序后能否拆分为一个严格 单调递减和严格 单调递增的数组。
很明显有数字出现三次不可,否则必定有解。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 fun main (args: Array <String >) { val n: Int = readLine()!!.toInt() var a = readLine()!!.split(" " ).map {it.toInt()} val mp = HashMap<Int , Int >() var x = mutableListOf<Int >() var y = mutableListOf<Int >() var ok: Boolean = true for (i in a) { if (!mp.containsKey(i)) { mp.put(i, 0 ) x.add(i) } else if (mp.get (i) == 1 ) { y.add(i) } else { ok = false break } mp.put(i, mp.get (i)!!+1 ) } val cmp = Comparator { xx: Int , yy: Int -> xx - yy} x.sortWith(cmp) y.sortWith(cmp) y.reverse() if (ok) { println("YES" ) println(x.size) println(x.joinToString(" " )) println(y.size) println(y.joinToString(" " )) } else { println("NO" ) } }
贪心拆分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 import kotlin.math.log2import kotlin.math.floorimport kotlin.math.powprivate fun readInt () = readLine()!!.toInt()private fun readInts () = readLine()!!.split(" " ).map { it.toInt() }fun main (args: Array <String >) { val (n, k) = readInts() var tmp = n var cnt: Int = 0 var mp = Array<Int > (32 ) {0 } while (tmp > 0 ) { var y = floor(log2(tmp.toDouble())).toInt() var now: Int = 2.0 .pow(y).toInt() mp[y]++ cnt++ tmp -= now } if (n < k || k < cnt) println("NO" ) else { println("YES" ) for (i in 31 downTo 0 ) { if (mp[i] >= k - cnt) { mp[i] -= k - cnt; mp[i-1 ] += (k - cnt) * 2 cnt = k break } mp[i-1 ] += mp[i] * 2 cnt += mp[i] mp[i] = 0 } for (i in 0. .31 ) for (j in 1. .mp[i]) print(2.0 .pow(i).toInt().toString() + " " ) } }
F. Boxers 大概左右各扫一遍乱搞一下?
网络流可以秒……但是Kotlin不会写网络流。
推荐的Kotlin竞赛学习资料 Kotlin的开发者Roman Elizarov算法模板库
巧用Kotlin:内置函数let、also、with、run、apply大大提高你的开发效率!
语法糖
类前面要加 open
关键字才能被继承。
多用 when
关键字替代 if
。