Go-ACM模式的输入输出

128 阅读3分钟

想要了解 Go 在 ACM 模式的输入输出,牛客输入输出训练场 就必须要去练一下

牛客输入输出训练场的 10 道题能够很好的了解到 fmtbufio 这两个包的用法

A+B(1)

输入描述: 输入包括两个正整数a,b(1 <= a, b <= 1000),输入数据包括多组。

输出描述: 输出a+b的结果

输入:
1 5
10 20

输出:
6
30

这里并没有说明什么时候终止,那么只需要判断 fmt.Scan() 所返回的字节数是否为 0 即可

package main

import (
    "fmt"
)

func main() {
    var a, b int
    
    for {
        nByte, _ := fmt.Scan(&a, &b)
        if nByte == 0 {
            break
        }
        fmt.Println(a+b)
    }
}

A+B(2)

这第二题就多了个元素,就是要先输入行数,再确定有多少组数据

package main

import (
    "fmt"
)

func main() {
    var row, a, b int
    
    nByte, _ := fmt.Scan(&row) // 接收第一个数据 row
    if nByte == 0 {
        return
    }
    
    for i := 0; i < row; i++ { // 再 for 循环来输入一组一组的数据
        n, _ := fmt.Scan(&a, &b)
        if n == 0 {
            return
        }
        
        fmt.Println(a+b)
    }
}

A+B(3)

第三题就加个判断条件即可

package main

import "fmt"

func main() {
    var a, b int
    
    for {
        n, _ := fmt.Scan(&a, &b)
        if n == 0 {
            return
        }
        
        if a == 0 && b == 0 { // 加上判断条件
            return
        }
        fmt.Println(a+b)
    }
}

A+b(4)

第四题就是第二题和第三题的结合版本

package main

import "fmt"

func main() {
    
    var count int
    
    for {
        n, _ := fmt.Scan(&count)
        if n == 0 || count == 0 {
            return
        }
       
        sum := 0
        for i := 0; i < count; i++ {
            var tmp int
            nByte, _ := fmt.Scan(&tmp)
            if nByte == 0 {
                return
            }
            sum += tmp
        }
        fmt.Println(sum)
    }
}

A+B(5)

还是差不多的输入输出模板,但是这里使用到了数组来接收输入

使用 nums := make([]int, cnt) 来预分配切片的容量,然后使用 fmt.Scan(&nums[j]) 来接收

package main

import "fmt"

func main() {
    var row int
    fmt.Scan(&row)
    
    for i := 0; i < row; i++ {
        var cnt int
        fmt.Scan(&cnt)
        
        nums := make([]int, cnt)
        for j := 0; j < cnt; j++ {
            fmt.Scan(&nums[j])
        }
        fmt.Println(sum(nums))
    }
}

func sum(nums []int) int {
    res := 0
    for _, val := range nums {
        res += val
    }
    return res
}

A+b(6)

这道题也差不多

package main

import "fmt"

func main() {
    
    var cnt int
    for {
        n, _ := fmt.Scan(&cnt)
        if n == 0 {
            break
        }
        nums := make([]int, cnt)
        for i := 0; i < cnt; i++ {
            fmt.Scan(&nums[i])
        }
        fmt.Println(sumnums(nums))
    }
}

func sumnums(nums []int) int {
    num := 0
    for _, val := range nums {
        num += val
    }
    return num
}

A+b(7)

嘿嘿,第七题终于有点不一样了,前面的几道题要么有限制输入的行数,要么有限制一组数据的个数,这种情况其实就自带了退出循环的特点

但是第七题他没有任何行数和数据个数的限制,这时候就可以使用到 bufio 包了

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin) // os.Stdin 接收标准输入,也就是控制台的输入
	for scanner.Scan() { // 数据
		input := strings.Split(scanner.Text(), " ") // 使用空格切割
		sum := 0
		for idx := range input {
			num, _ := strconv.Atoi(input[idx])
			sum += num
		}
		fmt.Println(sum)
	}
}
  • sacnner.Scan() 在每一次循环都会扫描一行,这样就不用判断输入了多少个
  • scanner.Text() 拿到扫描该行的数据
  • strings.Split(scanner.Text(), " ") 就是将扫描的数据以空格进行切割,返回一个字符串切片 []string
  • strconv.Atoi() 将扫描到的 string 转化为 int 类型

字符串排序(1)

字符串排序的题目,其实和接收数字是差不多的,只不过是多了排序相关的东西

在 go 包里,有自带的排序函数:

  • sort.Ints():给包含类型为 int 的数据切片进行从小到大排序
  • sort.Strings():同理,给字符串下切片,按照 ASCII 码值,从小到大每一位分别比较

其他的类推,比如 sort.Float64s()

那么这些字符串排序的题也是比较容易可以解的

package main

import (
	"fmt"
	"sort"
)

func main() {

	var cnt int
	for {
		n, _ := fmt.Scan(&cnt)
		if n == 0 {
			return
		}

		strSlice := make([]string, cnt)
		for i := 0; i < cnt; i++ {
			fmt.Scan(&strSlice[i])
		}
		// 排序
		sort.Strings(strSlice)
		printStr(strSlice)
	}
}

func printStr(strArr []string) {
	for _, str := range strArr {
		fmt.Print(str + " ")
	}
}

字符串排序(2)

package main

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

func main() {

	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input := strings.Split(scanner.Text(), " ")

		// 排序
		sort.Strings(input)
		printStr(input)
		fmt.Println() // 记得换行
	}
}

func printStr(strArr []string) {
	for _, str := range strArr {
		fmt.Print(str + " ")
	}
}

字符串排序(3)

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input := strings.Split(scanner.Text(), ",") // 使用逗号进行分割
		sort.Strings(input)
		printStr(input)
		fmt.Println()
	}
}

func printStr(strArr []string) {
	for idx, str := range strArr {
		if idx != len(strArr)-1 {
			fmt.Print(str + ",")
		} else {
			fmt.Print(str)
		}
	}
}

通过了上面这十道题,基本上对于 ACM 模式下的输入输出有基本了解了