用Golang刷OJ,虽然很奇怪,但作为蒟蒻,为了笔试和面试也只能硬着头皮刷了,然后就碰到了一堆奇怪的问题。
这篇主要讲输入的一些坑。 首先,我们知道读取控制台输入可以用fmt包或者bufio包,这里尽量不要用fmt的Scan(也包括Scanf,Scanln等等),虽然用法和c的Scanf差不多,但是效率低太多,多调用几次就TLE的节奏。推荐使用bufio.NewScanner,一般来说绝大部分的题目用这个就够了。但是,bufio.NewScanner的底层buf数组有个最大缓存限制的,是64K,也就是说按照标准的Scan,一行最多64K的数据大小,题目里如果超过这个范围,比如一行20万数据,每个数据范围还是int32内的,那这就至少800K的大小了,还没算上中间的空格,所以默认的buf空间肯定是不够的,这时候需要调用Buffer方法,手动给Scanner分配一个满足题目空间的buf数组,其余照常。(当然,除了这种方法,还可以用bufio的NewReader,调用ReadString方法,可以完整地读取一行,而不必考虑一行的长度,因为底层帮忙做了处理)
附个题目:https://www.acwing.com/problem/content/description/105/
以及AC代码:
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
func main() {
sc := bufio.NewScanner(os.Stdin)
bs := make([]byte, 2000*1024)
sc.Buffer(bs, len(bs))
sc.Scan()
N, _ := strconv.Atoi(sc.Text()) repo := make(map[int]int, N)
sc.Scan()
l := strings.Split(sc.Text(), " ")
for _, s := range l {
v, _ := strconv.Atoi(s)
repo[v]++
}
sc.Scan()
M, _ := strconv.Atoi(sc.Text())
movie := make([][3]int, M)
sc.Scan()
l = strings.Split(sc.Text(), " ")
for i, s := range l {
movie[i][0], _ = strconv.Atoi(s)
movie[i][2] = i+1
}
sc.Scan()
l = strings.Split(sc.Text(), " ")
for i, s := range l {
movie[i][1], _ = strconv.Atoi(s)
}
sort.Slice(movie, func(i, j int) bool {
if repo[movie[i][0]] == repo[movie[j][0]] {
return repo[movie[i][1]] > repo[movie[j][1]]
} else {
return repo[movie[i][0]] > repo[movie[j][0]]
}
})
fmt.Println(movie[0][2])
}
【Golang在OJ系统上的坑-输入相关】
推荐阅读
- leetcode刷题|【leetcode每日刷题】35. Search Insert Position
- leetcode 第35题 搜索插入位置
- 数组(简单题)(搜索插入位置)
- 搜索插入位置(Search Insert Position)
- GO|马拉车算法
- GO|Golang刷题遇到的坑,sort排序相关
- leetcode题解-71. Simplify Path && 43. Multiply Strings
- 两数相加2(java)LeetCode第445题
- LeetCode【链表】2. 两数相加