package main import ( "bufio" "fmt" "io" "os" "strconv" "strings" ) func main() { sc := NewScanner(os.Stdin) pr := NewPrinter(os.Stdout) defer pr.writer.Flush() N := sc.NextInt() T := sc.NextIntSlice() s := sc.NextIntSlice() A := 0 count := 0 for i := 0; i < N; i++ { P := s[i] if A < P { A = P + T[i] - 1 count++ } } fmt.Println(count) } // Scanner は入力を効率的に読み取るためのカスタム構造体です。 // 内部で bufio.Reader を利用し、1行読み込んだ後に tokens に分割して管理します。 type Scanner struct { reader *bufio.Reader tokens []string pos int } // NewScanner は与えられた io.Reader から Scanner を生成します。 func NewScanner(r io.Reader) *Scanner { return &Scanner{reader: bufio.NewReader(r)} } // NextString は空白区切りの次のトークンを返します。 // 内部にトークンがなければ新たに1行読み込み、tokens に分割して返します。 func (s *Scanner) NextString() string { if s.pos < len(s.tokens) { token := s.tokens[s.pos] s.pos++ return token } // トークンがない場合は新たに行を読み込む for { line, err := s.reader.ReadString('\n') if err != nil { // エラー時も部分的に読み込んだ行があれば処理する line = strings.TrimRight(line, "\r\n") if len(line) > 0 { s.tokens = strings.Fields(line) s.pos = 0 if len(s.tokens) > 0 { token := s.tokens[s.pos] s.pos++ return token } } panic(err) } line = strings.TrimRight(line, "\r\n") if len(line) == 0 { continue // 空行はスキップ } s.tokens = strings.Fields(line) s.pos = 0 if len(s.tokens) > 0 { token := s.tokens[s.pos] s.pos++ return token } } } // NextInt は次のトークンを整数に変換して返します。 func (s *Scanner) NextInt() int { token := s.NextString() val, err := strconv.Atoi(token) if err != nil { panic(err) } return val } func (s *Scanner) NextIntSlice() []int { split := strings.Split(s.NextLine(), " ") n := len(split) slice := make([]int, n) for i := 0; i < n; i++ { slice[i], _ = strconv.Atoi(split[i]) } return slice } // NextLine は、未消化のトークンがあればそれらを結合して返すか、 // もしくは新たに1行丸ごと読み込んで返します。 func (s *Scanner) NextLine() string { if s.pos < len(s.tokens) { line := strings.Join(s.tokens[s.pos:], " ") s.tokens = nil s.pos = 0 return line } line, err := s.reader.ReadString('\n') if err != nil { return strings.TrimRight(line, "\r\n") } return strings.TrimRight(line, "\r\n") } // Printer は出力を効率的に行うためのカスタム構造体です。 // 内部で bufio.Writer を利用しています。 type Printer struct { writer *bufio.Writer } // NewPrinter は与えられた io.Writer から Printer を生成します。 func NewPrinter(w io.Writer) *Printer { return &Printer{writer: bufio.NewWriter(w)} } // Print は引数をそのまま出力します(改行なし)。 func (p *Printer) Print(a ...interface{}) { s := fmt.Sprint(a...) p.writer.WriteString(s) } // Println は引数をスペース区切りで出力し、最後に改行を付けます。 func (p *Printer) Println(a ...interface{}) { s := fmt.Sprintln(a...) p.writer.WriteString(s) } // Printf はフォーマットに従って出力します。 func (p *Printer) Printf(format string, a ...interface{}) { s := fmt.Sprintf(format, a...) p.writer.WriteString(s) } // PrintIntSlice は整数のスライスをスペース区切りで出力し、最後に改行を付けます。 func (p *Printer) PrintIntSlice(slice []int) { for i, v := range slice { if i > 0 { p.writer.WriteString(" ") } p.writer.WriteString(strconv.Itoa(v)) } p.writer.WriteString("\n") } // PrintStringSlice は文字列のスライスをスペース区切りで出力し、最後に改行を付けます。 func (p *Printer) PrintStringSlice(slice []string) { p.writer.WriteString(strings.Join(slice, " ")) p.writer.WriteString("\n") } // Ordered は、順序比較が可能な型の制約です。 // チルダ記法(~)を用いて、基底型が同じ型を含むようにしています。 type Ordered interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string } // Min は、2 つの値のうち小さい方を返します。 func Min[T Ordered](a, b T) T { if a < b { return a } return b } // Max は、2 つの値のうち大きい方を返します。 func Max[T Ordered](a, b T) T { if a > b { return a } return b }