通过前缀和来看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 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
劲夫学编程1 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪1 小时前
孤岛的总面积(Dfs C#
算法·深度优先
秃头佛爷2 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨2 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
浮生如梦_3 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
励志成为嵌入式工程师5 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法