123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package main
- import (
- "bufio"
- "fmt"
- "math"
- "os"
- "strconv"
- "strings"
- )
- func readInt(s *bufio.Scanner) int {
- s.Scan()
- i, _ := strconv.ParseInt(s.Text(), 10, 32)
- return int(i)
- }
- func read5Float64(s *bufio.Scanner) (float64, float64, float64, float64, float64) {
- s.Scan()
- n := strings.Split(s.Text(), " ")
- n1, _ := strconv.ParseFloat(n[0], 64)
- n2, _ := strconv.ParseFloat(n[1], 64)
- n3, _ := strconv.ParseFloat(n[2], 64)
- n4, _ := strconv.ParseFloat(n[3], 64)
- n5, _ := strconv.ParseFloat(n[4], 64)
- return n1, n2, n3, n4, n5
- }
- func circularSegment(r, theta float64) float64 {
- return r * r * (theta - math.Sin(theta)) / 2
- }
- func hitFly(scanner *bufio.Scanner) []float64 {
- caseCnt := readInt(scanner)
- answer := make([]float64, caseCnt)
- for i := 0; i < caseCnt; i++ {
- // r fly, r outer ring, thickness, r string and gap length
- f, R, t, r, g := read5Float64(scanner)
- if g <= 2*f {
- answer[i] = 1.
- continue
- }
- rad := R - t - f
- sqrRad := rad * rad
- gridArea := (g - 2*f) * (g - 2*f)
- area := 0.
- for x1 := r + f; x1 < rad; x1 += g + 2*r { // 1st quadrant, x1, y1 is the coord of br
- for y1 := r + f; y1 < rad; y1 += g + 2*r {
- x2, y2 := x1+g-2*f, y1+g-2*f
- if x1*x1+y1*y1 >= sqrRad {
- continue
- }
- switch {
- case x2*x2+y2*y2 <= sqrRad: // All points inside circle
- area += gridArea
- case x1*x1+y2*y2 >= sqrRad && x2*x2+y1*y1 >= sqrRad:
- // Only x1, y1 inside
- area += circularSegment(rad, math.Pi/2-math.Asin(x1/rad)-math.Asin(y1/rad))
- area += (math.Sqrt(sqrRad-x1*x1) - y1) * (math.Sqrt(sqrRad-y1*y1) - x1) / 2
- case x1*x1+y2*y2 >= sqrRad: // x1, y1 and x2, y1 inside
- area += circularSegment(rad, math.Acos(x1/rad)-math.Acos(x2/rad))
- area += ((math.Sqrt(sqrRad-x1*x1) - y1) + (math.Sqrt(sqrRad-x2*x2) - y1)) * (x2 - x1) / 2
- case x2*x2+y1*y1 >= sqrRad: // x1, y1 and x1, y2 inside
- area += circularSegment(rad, math.Asin(y2/rad)-math.Asin(y1/rad))
- area += ((math.Sqrt(sqrRad-y2*y2) - x1) + (math.Sqrt(sqrRad-y1*y1) - x1)) * (y2 - y1) / 2
- default: // All except x2, y2 inside
- area += circularSegment(rad, math.Asin(y2/rad)-math.Acos(x2/rad))
- area += gridArea - (x2-math.Sqrt(sqrRad-y2*y2))*(y2-math.Sqrt(sqrRad-x2*x2))/2
- }
- }
- }
- answer[i] = 1. - area/(math.Pi*R*R/4)
- }
- return answer
- }
- func main() {
- inputFiles := []string{"C-small-practice.in", "C-large-practice.in", "test.in"}
- outputFiles := []string{"result-small.out", "result-large.out", "test.out"}
- const (
- small = iota
- large
- test
- )
- fileType := large
- fin, _ := os.Open(inputFiles[fileType])
- defer fin.Close()
- scanner := bufio.NewScanner(fin)
- answer := hitFly(scanner)
- fout, _ := os.Create(outputFiles[fileType])
- defer fout.Close()
- for i, ans := range answer {
- s := fmt.Sprintf("Case #%d: %f\n", i+1, ans)
- fout.WriteString(s)
- }
- }
|