For problem statement at 0-999/600-699/660-669/662/problemE.txt this is a correct solution, but verifier at 0-999/600-699/660-669/662/verifierE.go ends with case 3 failed: expected 1 got 2
exit status 1 can you fix the verifier? package main
import (
"bufio"
"fmt"
"math"
"math/bits"
"os"
"sort"
)
const EPS = 1e-9
type Opt struct {
w int
x int
}
type LPSolver struct {
m, n int
B, N []int
D [][]float64
}
func NewLPSolver(A [][]float64, b, c []float64) *LPSolver {
m := len(b)
n := len(c)
D := make([][]float64, m+2)
for i := range D {
D[i] = make([]float64, n+2)
}
B := make([]int, m)
N := make([]int, n+1)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
D[i][j] = A[i][j]
}
}
for i := 0; i < m; i++ {
B[i] = n + i
D[i][n] = -1
D[i][n+1] = b[i]
}
for j := 0; j < n; j++ {
N[j] = j
D[m][j] = -c[j]
}
N[n] = -1
D[m+1][n] = 1
return &LPSolver{m: m, n: n, B: B, N: N, D: D}
}
func (s *LPSolver) Pivot(r, c int) {
inv := 1.0 / s.D[r][c]
for i := 0; i < s.m+2; i++ {
if i == r {
continue
}
for j := 0; j < s.n+2; j++ {
if j == c {
continue
}
s.D[i][j] -= s.D[r][j] * s.D[i][c] * inv
}
}
for j := 0; j < s.n+2; j++ {
if j != c {
s.D[r][j] *= inv
}
}
for i := 0; i < s.m+2; i++ {
if i != r {
s.D[i][c] *= -inv
}
}
s.D[r][c] = inv
s.B[r], s.N[c] = s.N[c], s.B[r]
}
func (s *LPSolver) Simplex(phase int) bool {
x := s.m
if phase == 2 {
x = s.m + 1
}
for {
c := -1
for j := 0; j <= s.n; j++ {
if phase == 2 && s.N[j] == -1 {
continue
}
if c == -1 || s.D[x][j] < s.D[x][c]-EPS || (math.Abs(s.D[x][j]-s.D[x][c]) <= EPS && s.N[j] < s.N[c]) {
c = j
}
}
if s.D[x][c] >= -EPS {
return true
}
r := -1
for i := 0; i < s.m; i++ {
if s.D[i][c] <= EPS {
continue
}
if r == -1 {
r = i
} else {
lhs := s.D[i][s.n+1] / s.D[i][c]
rhs := s.D[r][s.n+1] / s.D[r][c]
if lhs < rhs-EPS || (math.Abs(lhs-rhs) <= EPS && s.B[i] < s.B[r]) {
r = i
}
}
}
if r == -1 {
return false
}
s.Pivot(r, c)
}
}
func (s *LPSolver) Solve() (feasible bool, bounded bool, val float64, x []float64) {
r := 0
for i := 1; i < s.m; i++ {
if s.D[i][s.n+1] < s.D[r][s.n+1] {
r = i
}
}
if s.m > 0 && s.D[r][s.n+1] < -EPS {
s.Pivot(r, s.n)
if !s.Simplex(2) || s.D[s.m+1][s.n+1] < -EPS {
return false, false, 0, nil
}
if s.D[s.m+1][s.n+1] > EPS {
return false, false, 0, nil
}
if s.B[r] == -1 {
c := 0
for j := 1; j <= s.n; j++ {
if s.D[r][j] < s.D[r][c]-EPS || (math.Abs(s.D[r][j]-s.D[r][c]) <= EPS && s.N[j] < s.N[c]) {
c = j
}
}
s.Pivot(r, c)
}
}
if !s.Simplex(1) {
return true, false, math.Inf(1), nil
}
x = make([]float64, s.n)
for i := 0; i < s.m; i++ {
if s.B[i] >= 0 && s.B[i] < s.n {
x[s.B[i]] = s.D[i][s.n+1]
}
}
return true, true, s.D[s.m][s.n+1], x
}
type IntSolver struct {
baseA [][]float64
baseB []float64
c []float64
nvars int
varGroup []int
varMask []int
groupCnt []int
resCap [3]int
best int
}
func (s *IntSolver) buildAB(lb, ub []int) ([][]float64, []float64) {
rows := make([][]float64, 0, len(s.baseA)+2*s.nvars)
b := make([]float64, 0, len(s.baseB)+2*s.nvars)
rows = append(rows, s.baseA...)
b = append(b, s.baseB...)
for i := 0; i < s.nvars; i++ {
if lb[i] > 0 {
row := make([]float64, s.nvars)
row[i] = -1
rows = append(rows, row)
b = append(b, -float64(lb[i]))
}
if ub[i] < s.groupCnt[s.varGroup[i]] {
row := make([]float64, s.nvars)
row[i] = 1
rows = append(rows, row)
b = append(b, float64(ub[i]))
}
}
return rows, b
}
func (s *IntSolver) greedy(sol []float64, lb, ub []int) int {
cur := make([]int, s.nvars)
usedGroup := make([]int, len(s.groupCnt))
usedCap := [3]int{}
profit := 0
for i := 0; i < s.nvars; i++ {
v := int(math.Floor(sol[i] + 1e-8))
if v < lb[i] {
v = lb[i]
}
if v > ub[i] {
v = ub[i]
}
cur[i] = v
profit += v
g := s.varGroup[i]
usedGroup[g] += v
mask := s.varMask[i]
for j := 0; j < 3; j++ {
if (mask>>j)&1 == 1 {
usedCap[j] += v
}
}
}
remGroup := make([]int, len(s.groupCnt))
for i := range s.groupCnt {
remGroup[i] = s.groupCnt[i] - usedGroup[i]
if remGroup[i] < 0 {
return profit
}
}
remCap := [3]int{s.resCap[0] - usedCap[0], s.resCap[1] - usedCap[1], s.resCap[2] - usedCap[2]}
if remCap[0] < 0 || remCap[1] < 0 || remCap[2] < 0 {
return profit
}
idx := make([]int, s.nvars)
for i := 0; i < s.nvars; i++ {
idx[i] = i
}
sort.Slice(idx, func(a, b int) bool {
ia, ib := idx[a], idx[b]
sa, sb := bits.OnesCount(uint(s.varMask[ia])), bits.OnesCount(uint(s.varMask[ib]))
if sa != sb {
return sa < sb
}
fa := sol[ia] - float64(cur[ia])
fb := sol[ib] - float64(cur[ib])
if math.Abs(fa-fb) > 1e-9 {
return fa > fb
}
return ia < ib
})
for _, i := range idx {
g := s.varGroup[i]
add := ub[i] - cur[i]
if add > remGroup[g] {
add = remGroup[g]
}
mask := s.varMask[i]
for j := 0; j < 3; j++ {
if (mask>>j)&1 == 1 && add > remCap[j] {
add = remCap[j]
}
}
if add <= 0 {
continue
}
cur[i] += add
profit += add
remGroup[g] -= add
for j := 0; j < 3; j++ {
if (mask>>j)&1 == 1 {
remCap[j] -= add
}
}
}
return profit
}
func (s *IntSolver) dfs(lb, ub []int) {
A, b := s.buildAB(lb, ub)
lp := NewLPSolver(A, b, s.c)
feasible, bounded, val, sol := lp.Solve()
if !feasible || !bounded {
return
}
ubv := int(math.Floor(val + 1e-7))
if ubv <= s.best {
return
}
lbv := s.greedy(sol, lb, ub)
if lbv > s.best {
s.best = lbv
}
if ubv <= s.best {
return
}
sel := -1
bestFrac := 0.0
for i := 0; i < s.nvars; i++ {
v := sol[i]
f := math.Abs(v - math.Round(v))
if f > 1e-7 && f > bestFrac {
bestFrac = f
sel = i
}
}
if sel == -1 {
if ubv > s.best {
s.best = ubv
}
return
}
v := sol[sel]
fl := int(math.Floor(v + 1e-8))
ce := int(math.Ceil(v - 1e-8))
if ce <= ub[sel] {
lb2 := append([]int(nil), lb...)
if ce > lb2[sel] {
lb2[sel] = ce
}
s.dfs(lb2, ub)
}
if fl >= lb[sel] {
ub2 := append([]int(nil), ub...)
if fl < ub2[sel] {
ub2[sel] = fl
}
s.dfs(lb, ub2)
}
}
func (s *IntSolver) Solve() int {
lb := make([]int, s.nvars)
ub := make([]int, s.nvars)
for i := 0; i < s.nvars; i++ {
ub[i] = s.groupCnt[s.varGroup[i]]
}
s.best = 0
s.dfs(lb, ub)
return s.best
}
func feasibleOptions(n, total, hackable int) []Opt {
minSolved := total - hackable
res := []Opt{}
for lv := 1; lv <= 6; lv++ {
var L, R int
if lv < 6 {
L = n/(1<<lv) + 1
R = n / (1 << (lv - 1))
} else {
L = 0
R = n / 32
}
lo := minSolved
if L > lo {
lo = L
}
hi := total
if R < hi {
hi = R
}
if lo <= hi {
x := total - lo
res = append(res, Opt{w: 2 * lv, x: x})
}
}
return res
}
func main() {
in := bufio.NewReaderSize(os.Stdin, 1<<20)
var n int
fmt.Fscan(in, &n)
t := make([][3]int, n)
base := make([][3]int, n)
hackable := make([][3]bool, n)
totalSolved := [3]int{}
totalHackable := [3]int{}
for i := 0; i < n; i++ {
fmt.Fscan(in, &t[i][0], &t[i][1], &t[i][2])
for j := 0; j < 3; j++ {
x := t[i][j]
if x != 0 {
totalSolved[j]++
if x < 0 {
totalHackable[j]++
hackable[i][j] = true
x = -x
}
base[i][j] = 250 - x
}
}
}
opts := [3][]Opt{}
for j := 0; j < 3; j++ {
opts[j] = feasibleOptions(n, totalSolved[j], totalHackable[j])
}
bestBeaten := 0
for _, o0 := range opts[0] {
for _, o1 := range opts[1] {
for _, o2 := range opts[2] {
w := [3]int{o0.w, o1.w, o2.w}
cap := [3]int{o0.x, o1.x, o2.x}
your := 100 * (cap[0] + cap[1] + cap[2])
for j := 0; j < 3; j++ {
if t[0][j] > 0 {
your += w[j] * base[0][j]
}
}
alreadyBelow := 0
groupMap := map[int]int{}
for i := 1; i < n; i++ {
full := 0
hmask := 0
rv := [3]int{}
for j := 0; j < 3; j++ {
if base[i][j] == 0 {
continue
}
v := w[j] * base[i][j]
full += v
if hackable[i][j] {
hmask |= 1 << j
rv[j] = v
}
}
d := full - your
if d <= 0 {
alreadyBelow++
continue
}
if hmask == 0 {
continue
}
suff := [8]bool{}
for s := 1; s < 8; s++ {
if s&^hmask != 0 {
continue
}
sum := 0
for j := 0; j < 3; j++ {
if (s>>j)&1 == 1 {
sum += rv[j]
}
}
if sum >= d {
suff[s] = true
}
}
key := 0
for s := 1; s < 8; s++ {
if !suff[s] {
continue
}
minimal := true
for sub := (s - 1) & s; sub > 0; sub = (sub - 1) & s {
if suff[sub] {
minimal = false
break
}
}
if minimal {
key |= 1 << (s - 1)
}
}
if key != 0 {
groupMap[key]++
}
}
neutralized := 0
if len(groupMap) > 0 {
groupCnt := make([]int, 0, len(groupMap))
keys := make([]int, 0, len(groupMap))
for k, v := range groupMap {
keys = append(keys, k)
groupCnt = append(groupCnt, v)
}
varGroup := []int{}
varMask := []int{}
for g, key := range keys {
for mask := 1; mask < 8; mask++ {
if ((key >> (mask - 1)) & 1) == 1 {
varGroup = append(varGroup, g)
varMask = append(varMask, mask)
}
}
}
nvars := len(varGroup)
rows := len(groupCnt) + 3
A := make([][]float64, rows)
for i := 0; i < rows; i++ {
A[i] = make([]float64, nvars)
}
bv := make([]float64, rows)
for i, cnt := range groupCnt {
bv[i] = float64(cnt)
}
for j := 0; j < 3; j++ {
bv[len(groupCnt)+j] = float64(cap[j])
}
for i := 0; i < nvars; i++ {
g := varGroup[i]
mask := varMask[i]
A[g][i] = 1
for j := 0; j < 3; j++ {
if (mask>>j)&1 == 1 {
A[len(groupCnt)+j][i] = 1
}
}
}
c := make([]float64, nvars)
for i := range c {
c[i] = 1
}
solver := IntSolver{
baseA: A,
baseB: bv,
c: c,
nvars: nvars,
varGroup: varGroup,
varMask: varMask,
groupCnt: groupCnt,
resCap: cap,
}
neutralized = solver.Solve()
}
beaten := alreadyBelow + neutralized
if beaten > bestBeaten {
bestBeaten = beaten
}
}
}
}
fmt.Println(n - bestBeaten)
}
func min(a, b int) int {
if a < b {
return a
}
return b
}