Looking at this problem, I need to find pairs of persons (A, B) who will make eye contact at least once during a full 360° rotation.
**Key Insight:** Both persons rotate clockwise at the same angular speed. Person A looks in direction θ_A(t) = θ_A(0) - ωt, and person B looks in direction θ_B(t) = θ_B(0) - ωt.
For A and B to make eye contact:
- A must look toward B: the direction from A to B equals θ_A(t)
- B must look toward A: the direction from B to A equals θ_B(t)
The direction from A to B and from B to A differ by exactly π.
So we need: θ_A(t) = angle(B - A) and θ_B(t) = angle(A - B) = angle(B - A) + π
Since θ_A(t) = θ_A(0) - ωt and θ_B(t) = θ_B(0) - ωt:
From first equation: ωt = θ_A(0) - angle(B - A)
From second equation: ωt = θ_B(0) - angle(B - A) - π
So: θ_A(0) - angle(B - A) = θ_B(0) - angle(B - A) - π (mod 2π)
This simplifies to: θ_A(0) - θ_B(0) ≡ -π (mod 2π), or equivalently θ_A(0) - θ_B(0) ≡ π (mod 2π).
Wait, let me recheck. θ_A(0) = θ_B(0) - π (mod 2π), meaning θ_A(0) + π ≡ θ_B(0) (mod 2π).
So the initial direction of A's gaze and the initial direction of B's gaze must differ by exactly π. In other words, they must initially look in **opposite** directions.
The initial direction for person i is the direction from (x_i, y_i) to (u_i, v_i), which is atan2(v_i - y_i, u_i - x_i).
Two persons make eye contact iff their initial looking directions differ by exactly π. The opposite of direction (dx, dy) is (-dx, -dy). We can normalize directions by reducing (dx, dy) to their coprime form with a canonical sign.
For each person, compute (dx, dy) = (u_i - x_i, v_i - y_i), reduce to coprime form with canonical sign. Two persons pair up if one has direction (a, b) and the other has (-a, -b) in canonical form. We can group by canonical direction and count pairs between opposite groups.
```go
package main
import (
"bufio"
"fmt"
"os"
)
func gcd(a, b int64) int64 {
for b != 0 {
a, b = b, a%b
}
return a
}
func abs64(x int64) int64 {
if x < 0 {
return -x
}
return x
}
func normalize(dx, dy int64) (int64, int64) {
g := gcd(abs64(dx), abs64(dy))
dx /= g
dy /= g
// canonical: first nonzero component positive
if dx < 0 || (dx == 0 && dy < 0) {
dx = -dx
dy = -dy
}
return dx, dy
}
type pair struct {
x, y int64
}
func main() {
reader := bufio.NewReader(os.Stdin)
writer := bufio.NewWriter(os.Stdout)
defer writer.Flush()
var t int
fmt.Fscan(reader, &t)
for ; t > 0; t-- {
var n int
fmt.Fscan(reader, &n)
// For each person, compute canonical direction and whether it was flipped
counts := make(map[pair]int64)
type entry struct {
norm pair
flipped bool
}
for i := 0; i < n; i++ {
var x, y, u, v int64
fmt.Fscan(reader, &x, &y, &u, &v)
dx := u - x
dy := v - y
ndx, ndy := normalize(dx, dy)
// Check if we flipped sign
// Original reduced: dx/g, dy/g. If normalize flipped, then direction is opposite
g := gcd(abs64(dx), abs64(dy))
rdx, rdy := dx/g, dy/g
flipped := (rdx != ndx || rdy != ndy)
_ = flipped
// Store as (canonical_dir, sign): sign=0 means original, sign=1 means flipped
if rdx == ndx && rdy == ndy {
counts[pair{ndx*2, ndy*2}]++
} else {
counts[pair{ndx*2 + 1, ndy*2 + 1}]++
}
}
// Pairs: same canonical direction, different sign
// Regroup
canon := make(map[pair][2]int64)
for k, v := range counts {
cx, cy := k.x/2, k.y/2
sign := k.x % 2
key := pair{cx, cy}
arr := canon[key]
arr[sign] += v
canon[key] = arr
}
var ans int64
for _, arr := range canon {
ans += arr[0] * arr[1]
}
fmt.Fprintln(writer, ans)
}
}
```