# 第 47 场双周赛题解
# Q1 1779. 找到最近的有相同 X 或 Y 坐标的点 (opens new window)
模拟即可。多个相同时,返回下标最小,即从小到大遍历,比较当前值时用而不是即可。
时间复杂度:
class Solution1779 {
fun nearestValidPoint(x: Int, y: Int, points: Array<IntArray>): Int {
var ans = -1
var cur = Int.MAX_VALUE
for (i in points.indices) {
if (points[i][0] == x || points[i][1] == y) {
if (cur > abs(points[i][0] - x) + abs(points[i][1] - y)) {
ans = i
cur = abs(points[i][0] - x) + abs(points[i][1] - y)
}
}
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Q2 1780. 判断一个数字是否可以表示成三的幂的和 (opens new window)
由于数字不大,比赛时直接暴力把所有组合求出来了...
class Solution1780 {
fun checkPowersOfThree(n: Int): Boolean {
val cur = arrayListOf<Int>()
var c = 1
for (i in 0 until 14) {
cur.add(c)
c *= 3
}
return n in cur.toIntArray().toAllSubSet()
}
}
/**
* 获取所有subSet的可能的和
* */
fun IntArray.toAllSubSet(): HashSet<Int> {
val set = hashSetOf<Int>()
val n = this.size
for (i in 0..(1 shl n)) {
var tmp = 0
for (j in 0 until n) {
if (i and (1 shl j) != 0) tmp += this[j]
}
set.add(tmp)
}
return set
}
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
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
不过实际上,可以把原数字转换为三进制,然后只允许出现即可,若有2出现,则证明其中某一个3的幂需要使用两次。
class Solution1780 {
fun checkPowersOfThree(n: Int): Boolean {
return "2" !in n.toString(3)
}
}
1
2
3
4
5
2
3
4
5
# Q3 1781. 所有子字符串美丽值之和 (opens new window)
数据范围,直接暴力没有压力。只是需要注意,没有的字符不参与最大最小的比较,因此每次计算时需要一次为的字符。
class Solution1781 {
fun beautySum(s: String): Int {
var ans = 0
for (i in s.indices) {
val cur = IntArray(26)
for (j in i until s.length) {
cur[s[j] - 'a']++
ans += cur.filter { it != 0 }.max()!! - cur.filter { it != 0 }.min()!!
}
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Q4 1782. 统计点对的数目 (opens new window)
中与任意一个点相连的数目,可以记为,则与两个点相连的数目应为。
- 先将每个点的连接线都计算出来,充实数组
- 将边记录起来,用于后续减去不满足的
- 根据遍历,双指针+二分快速查找总和满足要求的(可以提前按照出入度排序,降低复杂度)
- 然后通过之前记录的边,把总和满足但减去重复后不满足的结果减去
时间复杂度
class Solution1782 {
fun countPairs(n: Int, edges: Array<IntArray>, queries: IntArray): IntArray {
val deg = HashMap<Int, Int>()
val edge = HashMap<Int, Int>()
edges.forEach {
it.sort()
deg[it[0]] = deg.getOrDefault(it[0], 0) + 1
deg[it[1]] = deg.getOrDefault(it[1], 0) + 1
val key = it[0] * (n + 1) + it[1]
edge[key] = edge.getOrDefault(key, 0) + 1
}
val ans = IntArray(queries.size)
val s = ArrayList(deg.values.sorted())
while (s.size != n)
s.add(0, 0)
queries.forEachIndexed { i, it ->
for (j in 0 until n) {
var left = j + 1
var right = n - 1
while (left <= right) {
val mid = (left + right) / 2
if (s[j] + s[mid] > it) {
right = mid - 1
} else {
left = mid + 1
}
}
ans[i] += n - left
}
for ((key, value) in edge) {
val u = key / (n + 1)
val v = key % (n + 1)
if (deg[u]!! + deg[v]!! > it && deg[u]!! + deg[v]!! - value <= it) {
ans[i]--
}
}
}
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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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