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) } }