# 第 281 场周赛题解 (opens new window)

# Q1 2180. 统计各位数字之和为偶数的整数个数 (opens new window)

生模拟...

class SolutionA {
    fun countEven(num: Int): Int {
        var ans = 0
        for (i in 1..num) {
            var cur = 0
            i.toString().forEach {
                cur += it - '0'
            }
            if (cur % 2 == 0) {
                ans++
            }
        }
        return ans
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Q2 2181. 合并零之间的节点 (opens new window)

链表题直接转数组就最方便了...

class SolutionB {
    fun mergeNodes(head: ListNode?): ListNode? {
        if (head == null) return null
        val ans = ArrayList<Int>()
        var tmp = 0
        head.toIntArray().forEach {
            if (it == 0 && tmp != 0) {
                ans.add(tmp)
                tmp = 0
            } else {
                tmp += it
            }
        }
        return ans.toIntArray().toListNode()
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Q3 2182. 构造限制重复的字符串 (opens new window)

贪心着拿,拿到不能再拿为止!

class SolutionC {
    fun repeatLimitedString(s: String, repeatLimit: Int): String {
        val arr = IntArray(26)
        s.forEach {
            arr[it - 'a']++
        }
        var repeat = 0
        var repeatChar = -1
        val ans = StringBuilder()
        while (true) {
            var add = false
            for (i in 25 downTo 0) {
                if (arr[i] > 0 && (repeatChar != i || repeat != repeatLimit)) {
                    add = true
                    ans.append('a' + i)
                    arr[i]--
                    if (repeatChar == i) {
                        repeat++
                    } else {
                        repeatChar = i
                        repeat = 1
                    }
                    break
                }
            }
            if (!add) break
        }
        return ans.toString()
    }
}
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

# Q4 2183. 统计可以被 K 整除的下标对数目 (opens new window)

将数组中每个值与kk的最大公约数算出来,之后只需要双层遍历这个最大公约数的值,互相相乘能够满足被kk整除,则可以选择这两个最大公约数的数量。注意:若两个最大公约数的值相同,需要使用选择,增加的数量为n(n1)/2n * (n - 1) / 2

class SolutionD {
    fun coutPairs(nums: IntArray, k: Int): Long {
        val map = HashMap<Int, Long>()
        nums.forEach {
            val key = gcd(it, k)
            map[key] = map.getOrDefault(key, 0) + 1
        }
        var ans = 0L
        val keys = map.keys.toList()
        for (i in keys.indices) {
            for (j in i until keys.size) {
                if (1L * keys[i] * keys[j] % k == 0L) {
                    ans += if (i == j) {
                        map[keys[i]]!! * (map[keys[i]]!! - 1) / 2
                    } else {
                        map[keys[i]]!! * map[keys[j]]!!
                    }
                }
            }
        }
        return ans
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23