Kotlin Heroes 5: ICPC Round (Practice)
传送门(点击传送)
注:这场练习赛整场只允许用 Kotlin 作为唯一语言。所以现学的,有语法不规范或者错误的地方欢迎教导和指正。
A. A+B (Trial Problem)
题意+思路:
单纯的A+B。( t 组数据)
代码:
import java.util.Scanner
fun main(args: Array<String>) {
val reader = Scanner(System.`in`)
val t:Int = reader.nextInt()
for(index in 1..t){
val a:Int = reader.nextInt()
val b:Int = reader.nextInt()
println("${
a+b}")
}
}
B. Candies and Two Sisters
题意:
有 n 块糖,让分成 a 和 b 两部分,问有多少种分法能使得 b > a。( t 组数据)
思路:
偶数块糖果,分法为总数折半减一;奇数块糖果,分法为总数折半。
代码:
import java.util.Scanner
fun main(args: Array<String>) {
val reader = Scanner(System.`in`)
val t:Int = reader.nextInt()
for(index in 1..t){
val n:Int = reader.nextInt()
if(n%2==0){
println("${
n/2-1}")
}else{
println("${
n/2}")
}
}
}
C. Equalize Prices Again
题意:
n 个物品,每个物品有自己的价格,让重新调整价格使得每个物品价格均为 x 且总价格不能低于之前所有物品总价格。( t 组数据)
思路:
先求出总价格,再用总价格除以物品个数并向上取整。
代码:
import java.util.Scanner
fun main(args: Array<String>) {
val reader = Scanner(System.`in`)
val t:Int = reader.nextInt()
for(i in 1..t){
val n:Int = reader.nextInt()
var sum:Int = 0
for(j in 1..n){
val get_num:Int = reader.nextInt()
sum += get_num
}
if(sum % n == 0) sum /= n
else sum = sum/n+1
println("$sum")
}
}
D. Construct the String
题意:
让构造一个长度为 n 且每连续的 a 个字符中都有 b 个不相同的字母。( t 组数据)
思路:
从 26 个字母里面随便选 b 个连续循环输出 n 个即可。
代码:
import java.util.Scanner
fun main(args: Array<String>) {
val reader = Scanner(System.`in`)
val t:Int = reader.nextInt()
for(index in 1..t){
val n:Int = reader.nextInt()
val a:Int = reader.nextInt()
val b:Int = reader.nextInt()
var now:Char = 'a'
for(i in 1..n){
print("$now")
now += 1
if(now > 'a' + b - 1 ){
now = 'a'
}
}
println("");
}
}
E. Binary String Minimizing
题意:
有一个长度为 n 的二进制码,你可以进行最多 k 次交换(每次交换可以交换相邻元素),使得这个二进制码尽可能的小。
思路:
设cont,是截至当前位置1的数量,f(i-1)为把之前所有1从i位置向左排列且不全时补0的移动数,那么f(i)=f(i-1)+cont,我们就从左往右循环不断计数不断累加,若一直不超范围则我们可以把所有1移到右端,若到某一步f(i)超过了k,那么对于位置i我们可以以i为右端点向左防止k-f(i-1)个连续的1,再放置1个0,再放置cont-(k-f(i-1))个1,剩下左边补0,对于i右边则按原串原封不动即可。
代码:
哭了,用这个语言不会写,怎么写怎么超时就很奇怪,明明复杂度只有 O ( n ) O(n) O(n)。底下这段代码会超时!
import java.util.Scanner
fun main() {
val reader = Scanner(System.`in`)
val t:Int
var n:Int
var k:Int
var sum_move:Int
var sum_step:Int
var cont:Int
var s:String
var no_thing:String
var flag:Boolean
t = reader.nextInt()
for(i in 1..t){
flag = true
n = reader.nextInt()
k = reader.nextInt()
no_thing = reader.nextLine()
s = reader.nextLine()
sum_move = 0; sum_step = 0; cont = 0
var ans:String = ""
for(j in 0..n-1){
if(s[j]=='1'){
cont++
}else{
if(sum_step + cont > k){
flag = false
val last:Int = k - sum_step
for(q in 1..sum_move) ans += "0"
for(q in 1..cont-last) ans += "1"
ans += "0"
for(q in 1..last) ans+="1"
for(q in j+1..n-1) ans+=s[q]
println("$ans")
break
}else{
sum_step += cont
sum_move++
}
}
}
if(flag){
for(j in 1..n-cont) ans+="0"
for(j in 1..cont) ans+="1"
println("$ans")
}
}
}
F. Platforms Jumping
题意:
有一条河,长度为 n ,你要从河左岸跳至右岸,设起跳位置为 x 则你可以跳至 [ x + 1 , x + d ] [x+1,x+d] [x+1,x+d],现在河上有 m 个木板,问通过摆放这些木板的位置可以顺利通过河面吗,如果可以输出yes并用数字的形式填上木板位置,如果不可以则输出NO。保证木板长度之和小于河面。
思路:
这题以前CF出过的题,贪心即可,只考虑木板以及河岸之间的跳跃,则需要跳跃 m+1 次,且每次跳跃河面距离最多为 d-1,(因为跳跃起点和落点均为木或地面,所以实际越过水面虽多为 d-1 )。先求出木板总和 sum ,并求出需要跳跃长度 n-sum ,每次跳跃长度为取(d-1,n - sum)中的最小值,每取完一个跳跃长度,将越过水面的长度加入sum中,以此循环直至结束。注意最一开始先判断若 s u m + ( m + 1 ) × ( d − 1 ) < n sum+(m+1)\times(d-1)<n sum+(m+1)×(d−1)<n 则无法跳过河。
代码:
import java.util.Scanner
fun min(a:Int, b:Int) : Int{
var ans:Int = 0
if(a < b) ans = a
else ans = b
return ans
}
fun main(args: Array<String>) {
val reader = Scanner(System.`in`)
val num = Array<Int>(1005, {
it})
val n:Int = reader.nextInt()
val m:Int = reader.nextInt()
val d:Int = reader.nextInt()
var sum:Int = 0
for(i in 1..m) {
num[i] = reader.nextInt()
sum += num[i]
}
if(sum+(m+1)*(d-1) < n){
println("NO")
}else{
println("YES")
for(i in 1..m){
val length:Int = min(n-sum,d-1)
for(j in 0..length-1){
print("0 ")
}
for(j in 1..num[i]){
print("$i ")
}
sum += length
}
for(i in 0..n-sum-1){
print("0 ")
}
println("")
}
}