通过前缀和来看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()
}
相关推荐
塔中妖1 小时前
【华为OD】查找接口成功率最优时间段
算法·链表·华为od
塔中妖1 小时前
【华为OD】最大子矩阵和
算法·华为od·矩阵
努力学习的小廉2 小时前
深入了解linux系统—— 线程同步
linux·服务器·数据库·算法
数据爬坡ing2 小时前
从挑西瓜到树回归:用生活智慧理解机器学习算法
数据结构·深度学习·算法·决策树·机器学习
luoganttcc2 小时前
小鹏汽车 vla 算法最新进展和模型结构细节
人工智能·算法·汽车
sinat_602035362 小时前
模块与包的导入
运维·服务器·开发语言·python
计算机学姐2 小时前
基于Python的旅游数据分析可视化系统【2026最新】
vue.js·后端·python·数据分析·django·flask·旅游
恋雨QAQ2 小时前
python函数和面向对象
开发语言·python
天雪浪子2 小时前
Python入门教程之逻辑运算符
开发语言·python
落羽的落羽3 小时前
【C++】特别的程序错误处理方式——异常机制
开发语言·c++