Golang在OJ系统上的坑-输入相关

用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])
}

 

你可能感兴趣的:(LeetCode刷题)