Kotlin Heroes 5: ICPC Round
传送门(点击传送)
注:这场比赛整场只允许用 Kotlin 作为唯一语言。之前练习赛现学的,有语法不规范或者错误的地方欢迎教导和指正。
A. Selling Hamburgers
题意:
有 n 个人,每人 a i a_i ai个金币,假设汉堡卖 m 元,如果 a i ⩾ m a_i\geqslant m ai⩾m,那么这个人就会花费 m 元买一个汉堡,商店就赚了 m 元,问现在商店最多可以赚多少元,汉堡费用自定。( t 组数据)
思路:
枚举汉堡费用,让 m = a i m=a_i m=ai 依次查看可以赚取多少金币,取最大值。
代码:
import java.util.Scanner
fun max(a:Long, b:Long) : Long{
var ans:Long = 0
if(a > b) ans = a
else ans = b
return ans
}
fun main() {
val reader = Scanner(System.`in`)
val num = Array<Long>(105, {
it.toLong()})
val t:Int = reader.nextInt()
for(index in 1..t){
val n:Int = reader.nextInt()
var ans:Long = 0
for(i in 1..n){
num[i] = reader.nextLong()
}
for(i in 1..n){
var sum:Long = 0
for(j in 1..n){
if(num[j]>=num[i]) sum+=num[i]
}
ans = max(ans,sum)
}
println("$ans")
}
}
B. Polycarp and the Language of Gods
题意:
有一篇笔记,用字母 ‘w’ 和字母 ‘v’ 构成,现在为了区分字母,会在字母下方画横线,在 w 下画横线就辨明 w 不会被错认为两个 v ,v 下面画横线就不会被和旁边的 v 一起错认为 w,问现在至少需要画多少个横线,可以让整篇笔记不会有歧义。( t 组数据)
思路:
遍历文章,当有连续的 k 个 v 的时候,需要至少标记 ⌊ k 2 ⌋ \left \lfloor \frac{k}{2}\right \rfloor ⌊2k⌋个 v ,当有 w 的时候就需要标记,依次遍历整个文章并给出答案。( ⌊ x ⌋ \left \lfloor x \right \rfloor ⌊x⌋ 为对x向下取整)
代码:
private fun readLn() = readLine()!! // string line
private fun readInt() = readLn().toInt() // single int
fun main() {
val t:Int = readInt()
for(index in 1..t){
val s:String = readLn()
val length:Int = s.length
var ans:Int = 0
var i:Int = 0
while(i<length){
if(s[i]=='w') ans++
if(s[i]=='v'){
var cont:Int = 1
while(i+1<length && s[i+1]=='v') {
i++
cont++
}
ans+=cont/2
}
i++
}
println("$ans")
}
}
C. Black Friday
题意:
有 n 个商品以及优惠指标 k ,规定以下优惠政策,当你购买了 m 个商品时,其中最便宜的 ⌊ m k ⌋ \left \lfloor \frac{m}{k}\right \rfloor ⌊km⌋ 个产品不收取任何费用。问当你怎么购买时白嫖的商品的价格之和最高,输出这个价格之和。( t 组数据)。
思路:
因为题目价格按非递减序列给出,所以不需排序,依次遍历买最贵的 i i i个商品,并对每次得出的白嫖商品价格之和取最大值就是最终答案。可以用前缀和维护。
代码:
private fun readLn() = readLine()!!
private fun readInt() = readLn().toInt()
private fun readStrings() = readLn().split(" ")
private fun readInts() = readStrings().map {
it.toInt() }
fun max(a:Int, b:Int) : Int{
var ans:Int = 0
if(a > b) ans = a
else ans = b
return ans
}
fun main() {
val t:Int = readInt()
for(index in 1..t){
val (n, k) = readInts()
val num = readInts()
val sum = Array<Int>(205, {
it})
var ans:Int = 0
sum[0]=0
for(i in 1..n){
sum[i]=sum[i-1]+num[i-1]
}
var cont:Int = 0
for(i in n downTo 1){
cont++
val get:Int = cont/k
ans=max(ans,sum[i+get-1]-sum[i-1])
}
println("$ans")
}
}
D. Used Markers
题意:
有 n 个教授要进行演讲,每场演讲都要用到马克笔在白板上进行板书,每位教授有一个习惯值 a i a_i ai,当他的这只马克笔被用过大于等于 a i a_i ai次时,他在演讲之前会要求换笔,教授位要求时禁止换笔。现在你作为调度人员,希望用的笔越多越好,这样保证了板书质量。让你给出教授的出场顺序保证换笔数量最多。
思路:
贪心,按照教授习惯值从小到大排序。分别给出两个指针 l l l指向最左, r r r指向最右,当当前笔使用次数未满足 a l a_l al的要求时,就安排右指针的教授。当满足 a l a_l al要求时,就安排左指针的教授。安排后移动效应指针,直至指针重合,安排完所有教授。
代码:
import java.util.Scanner
fun main() {
val reader = Scanner(System.`in`)
val t:Int = reader.nextInt()
val num = Array<Int>(505, {
it})
val ans = Array<Int>(505, {
it})
for(index in 1..t){
val n:Int = reader.nextInt()
val loc = Array<Int>(505, {
it})
for(i in 1..n){
num[i] = reader.nextInt()
}
var tmp:Int
for(i in 1..n-1) {
var mark:Int=i
var min:Int=num[i]
for(j in i+1..n){
if(num[j]<min){
mark=j;min=num[j]
}
}
tmp=num[mark];num[mark]=num[i];num[i]=tmp
tmp=loc[mark];loc[mark]=loc[i];loc[i]=tmp
}
var l:Int = 1
var r:Int = n
var cont:Int = 1
var ans_loc:Int = 1
ans[ans_loc]=loc[r]
while(l<r){
while(l<r-1 && cont<num[l]){
cont++;r--;ans_loc++
ans[ans_loc]=loc[r]
}
ans_loc++
ans[ans_loc]=loc[l]
l++
cont=1
}
for(i in 1..n){
print("${
ans[i]} ")
}
println("")
}
}
后面的用这语言写不动了(逃~)