通过前缀和来看golang的acm输入输出

前缀和

问题引入

go 复制代码
package main

import (
    "fmt"
)

func main() {
    var n, q, l, r int
    fmt.Scan(&n, &q)
    a := make([]int, n)
    ap := make([]int64, n + 1)
    ap[0] = 0

    for i := 0; i < n; i++ {
        fmt.Scan(&a[i])
        ap[i + 1] = ap[i] + int64(a[i])
    }
    for j := 0; j < q; j++ {
        fmt.Scan(&l, &r)
        fmt.Println(ap[r] - ap[l-1])
    }
}


考虑是不是输入太慢了,用Scanner试试

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func main() {
	/*fmt.Scan()不会处理换行符,所以后面用sc.Scan()会读取换行符*/
	/*改用fmt.Scanln()读取一行,且会丢弃换行符*/
	var n, q, l, r int
	//var s string
	fmt.Scan(&n, &q)
	//fmt.Scanln(s)
	//values := strings.Split(s, " ")
	//n, _ = strconv.Atoi(values[0])
	//q, _ = strconv.Atoi(values[1])
	ap := make([]int64, n+1)
	ap[0] = 0
	sc := bufio.NewScanner(os.Stdin)
	sc.Scan()
	sc.Scan()
	strs := strings.Split(sc.Text(), " ")
	for i := range strs {
		val, _ := strconv.Atoi(strs[i])
		ap[i+1] = ap[i] + int64(val)
	}
	for i := 0; i < q; i++ {
		fmt.Scan(&l, &r)
		fmt.Println(ap[r] - ap[l-1])
	}
}

// package main

// import (
//     "fmt"
// )

// func main() {
//     var n, q, l, r int
//     fmt.Scan(&n, &q)
//     a := make([]int, n)
//     ap := make([]int64, n + 1)
//     ap[0] = 0

//     for i := 0; i < n; i++ {
//         fmt.Scan(&a[i])
//         ap[i + 1] = ap[i] + int64(a[i])
//     }
//     for j := 0; j < q; j++ {
//         fmt.Scan(&l, &r)
//         fmt.Println(ap[r] - ap[l-1])
//     }
// }

本地goland运行:

但牛客上运行:

于是,开始对输入输出好好研究:

go 复制代码
package main

import (
	"bufio"
	"fmt"
    "os"
)

func main() {
	var (
        n, q, l, r int
        in = bufio.NewReader(os.Stdin)
        out = bufio.NewWriter(os.Stdout)
    )
	fmt.Fscan(in, &n, &q)
	a := make([]int, n)
	ap := make([]int64, n+1)
	ap[0] = 0

	for i := 0; i < n; i++ {
		fmt.Fscan(in, &a[i])
		ap[i+1] = ap[i] + int64(a[i])
	}
	for j := 0; j < q; j++ {
		fmt.Fscan(in, &l, &r)
        fmt.Fprintln(out, ap[r] - ap[l - 1])
		// fmt.Println(ap[r] - ap[l-1])
        out.Flush()
    }
}

那么在此前提下,如果第二行输入不一个个读入,用整行读入呢?

(其实到这,我就有了对自己之前行为的评价:之前代码的各种输入输出用的很混乱,想用哪一套就彻底用哪一套呗,快不快慢不慢的,看着就恶心)

go 复制代码
package main

// 前缀和很简单,往往输入数据会很变态,所以不能用fmt.Scan()和fmt.Println()
// 有好几种优化的输入输出

// 用封装好的bufio.NewReader(os.Stdin)和bufio.NewWriter(os.Stdout)

/*
var (
	n, q, l, r int
	in         = bufio.NewReader(os.Stdin)
	out        = bufio.NewWriter(os.Stdout)
)

func main() {
	fmt.Fscan(in, &n, &q)
	a := make([]int, n)
	ap := make([]int64, n+1)
	ap[0] = 0

	for i := 0; i < n; i++ {
		fmt.Fscan(in, &a[i])
		ap[i+1] = ap[i] + int64(a[i])
	}

	for j := 0; j < q; j++ {
		fmt.Fscan(in, &l, &r)
		fmt.Fprintln(out, ap[r]-ap[l-1])
		out.Flush()
	}
}
*/

// 用适合于整行读取的组合方法
/*
sc := bufio.NewScanner(os.Stdin)
bs := make([]byte, 20000 * 1024) //设置缓冲区的最大读取
readLine = func() (res string) {
	sc.Scan() //读一行
	l := strings.Split(sc.Text(), " ")
	var res string
	for _, s := range l {
		res += s
	}
	return
}
out = bufio.NewWriter(os.Stdout)

scanner.Buffer(bs, len(bs)) //设置缓冲区的最大读取
cur := readLine()
fmt.Fprint(out, cur)
out.Flush()
*/

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

var (
	n, p, l, r int
	sc         = bufio.NewScanner(os.Stdin) //按行扫描器
	out        = bufio.NewWriter(os.Stdout) //文件输出流(要用fmt.Fprint(out, ...))
	bs         = make([]byte, 20000*1024)   //设置缓冲区最大读取
	readLine   = func() (res []int) {       //把读取一行的操作封装成一个匿名函数
		sc.Scan()                             //扫描器读取一行
		strs := strings.Split(sc.Text(), " ") //将读取的字符串分割成切片
		res = make([]int, len(strs))          //这一句不能遗漏,返回值是切片类型,必须要有初始化
		for i, s := range strs {              //将切片中的每个元素转换为int类型,再存入返回值切片里
			x, _ := strconv.Atoi(s)
			res[i] = x
		}
		return
	}
)

func main() {
	sc.Buffer(bs, len(bs))         //设置缓冲区读取最大数量
	cur1 := readLine()             //读第一行
	ap := make([]int64, cur1[0]+1) //前缀和数组(切片)
	cur2 := readLine()             //读第二行
	for i := range cur2 {
		ap[i+1] = ap[i] + int64(cur2[i]) //求前缀和
	}
	for i := 0; i < cur1[1]-1; i++ { //求要求的区间内的数值和
		cur := readLine()
		fmt.Fprintln(out, ap[cur[1]]-ap[cur[0]-1])
	}
	//最后一组单独写是为了防止最后多个换行
	cur := readLine()
	fmt.Fprint(out, ap[cur[1]]-ap[cur[0]-1])
	//最后一下给Flush出来
	out.Flush()
}
相关推荐
CT随9 分钟前
Redis内存碎片详解
java·开发语言
anlog18 分钟前
C#在自定义事件里传递数据
开发语言·c#·自定义事件
奶香臭豆腐31 分钟前
C++ —— 模板类具体化
开发语言·c++·学习
游是水里的游37 分钟前
【算法day19】回溯:分割与子集问题
算法
不想当程序猿_37 分钟前
【蓝桥杯每日一题】分糖果——DFS
c++·算法·蓝桥杯·深度优先
晚夜微雨问海棠呀39 分钟前
长沙景区数据分析项目实现
开发语言·python·信息可视化
graceyun40 分钟前
C语言初阶习题【9】数9的个数
c语言·开发语言
南城花随雪。1 小时前
单片机:实现FFT快速傅里叶变换算法(附带源码)
单片机·嵌入式硬件·算法
小蜗牛慢慢爬行1 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
dundunmm1 小时前
机器学习之scikit-learn(简称 sklearn)
python·算法·机器学习·scikit-learn·sklearn·分类算法