小美的数组询问

题目

小美拿到了一个由正整数组成的数组,但其中有一些元素是未知的(用 0 来表示)。现在小美想知道,如果那些未知的元素在区间[l,r][l,r]范围内随机取值的话,数组所有元素之和的最小值和最大值分别是多少?共有qq次询问。

构思

直接记录非零元素之和,然后记录0元素的数目,最小值即为sum+0元素数目*取值最小值,最大值即为sum+0元素数目*取值最大值

代码实现

首次实现

使用scan进行输入

func main() {
    var n, q int
    fmt.Scan(&n, &q)
    nums := make([]int, n)
    number0 := 0
    sum := 0
    for i := 0; i < n; i++ {
        fmt.Scan(&nums[i])
        if nums[i] == 0 {
            number0++
        }
        sum += nums[i]
    }

    for i := 0; i < q; i++ {
        var l, r int
        fmt.Scan(&l, &r)
        fmt.Println(sum + number0 * l, sum + number0 * r)
    }
}

代码优化

我们发现代码的绝大部份时间都花在了读取数据上面,所以我们通过buffer来进行优化读取,减少数据读取时间

package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	// 读取 n 和 q
	line, _ := reader.ReadString('\n')
	fields := strings.Fields(line)
	n, _ := strconv.Atoi(fields[0])
	q, _ := strconv.Atoi(fields[1])

	// 读取数组 nums
	nums := make([]int, n)
	line, _ = reader.ReadString('\n')
	fields = strings.Fields(line)
	number0 := 0
	sum := 0
	for i := 0; i < n; i++ {
		nums[i], _ = strconv.Atoi(fields[i])
		if nums[i] == 0 {
			number0++
		}
		sum += nums[i]
	}

	// 处理查询
	for i := 0; i < q; i++ {
		line, _ := reader.ReadString('\n')
		fields := strings.Fields(line)
		l, _ := strconv.Atoi(fields[0])
		r, _ := strconv.Atoi(fields[1])

		// 计算结果
		result1 := sum + number0*l
		result2 := sum + number0*r

		// 输出结果
		fmt.Fprintln(writer, result1, result2)
	}
}

优化点

(1) 使用 bufio 加速输入输出

  • 使用 bufio.NewReader 和 bufio.NewWriter 来加速输入输出。
  • reader.ReadString('\n') 读取一行输入。
  • strings.Fields 将输入行拆分为字段。
  • strconv.Atoi 将字符串转换为整数。

(2) 减少重复计算

  • 在查询处理部分,直接使用 sum 和 number0 计算结果,避免了重复计算。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客企业服务