← Home
For problem statement at 0-999/0-99/30-39/39/problemK.txt this is a correct solution, but verifier at 0-999/0-99/30-39/39/verifierK.go ends with All tests passed can you fix the verifier? package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

type Object struct {
	rmin, rmax, cmin, cmax int
}

var N, M, K_objs int
var objs []Object

func uniqueSort(arr []int) []int {
	if len(arr) == 0 {
		return arr
	}
	sort.Ints(arr)
	n := 1
	for i := 1; i < len(arr); i++ {
		if arr[i] != arr[i-1] {
			arr[n] = arr[i]
			n++
		}
	}
	return arr[:n]
}

func solve(S []int) int64 {
	R1, R2, C1, C2 := 10000, -1, 10000, -1
	for _, idx := range S {
		obj := objs[idx]
		if obj.rmin < R1 {
			R1 = obj.rmin
		}
		if obj.rmax > R2 {
			R2 = obj.rmax
		}
		if obj.cmin < C1 {
			C1 = obj.cmin
		}
		if obj.cmax > C2 {
			C2 = obj.cmax
		}
	}

	U_max, D_max := 1, N

	var OL []Object
	var OR []Object

	for i := 0; i < len(objs); i++ {
		in_S := false
		for _, idx := range S {
			if idx == i {
				in_S = true
				break
			}
		}
		if in_S {
			continue
		}

		obj := objs[i]

		if obj.rmin <= R2 && obj.rmax >= R1 && obj.cmin <= C2 && obj.cmax >= C1 {
			return 0
		}

		if obj.cmin <= C2 && obj.cmax >= C1 {
			if obj.rmax < R1 {
				if obj.rmax+1 > U_max {
					U_max = obj.rmax + 1
				}
			}
			if obj.rmin > R2 {
				if obj.rmin-1 < D_max {
					D_max = obj.rmin - 1
				}
			}
		} else if obj.cmax < C1 {
			OL = append(OL, obj)
		} else if obj.cmin > C2 {
			OR = append(OR, obj)
		}
	}

	if U_max > R1 || D_max < R2 {
		return 0
	}

	L_always, R_always := 1, M
	for _, obj := range OL {
		if obj.rmax >= R1 && obj.rmin <= R2 {
			if obj.cmax+1 > L_always {
				L_always = obj.cmax + 1
			}
		}
	}
	for _, obj := range OR {
		if obj.rmax >= R1 && obj.rmin <= R2 {
			if obj.cmin-1 < R_always {
				R_always = obj.cmin - 1
			}
		}
	}

	if L_always > C1 || R_always < C2 {
		return 0
	}

	u_points := make([]int, 0, len(OL)+len(OR)+2)
	u_points = append(u_points, U_max, R1+1)
	for _, obj := range OL {
		if obj.rmax < R1 && obj.rmax+1 >= U_max {
			u_points = append(u_points, obj.rmax+1)
		}
	}
	for _, obj := range OR {
		if obj.rmax < R1 && obj.rmax+1 >= U_max {
			u_points = append(u_points, obj.rmax+1)
		}
	}
	u_points = uniqueSort(u_points)

	type Interval struct {
		start, end, L, R int
	}
	u_intervals := make([]Interval, 0, len(u_points))
	for i := 0; i < len(u_points)-1; i++ {
		st := u_points[i]
		en := u_points[i+1] - 1
		if st <= en {
			lt := L_always
			rt := R_always
			for _, obj := range OL {
				if obj.rmax < R1 && st <= obj.rmax {
					if obj.cmax+1 > lt {
						lt = obj.cmax + 1
					}
				}
			}
			for _, obj := range OR {
				if obj.rmax < R1 && st <= obj.rmax {
					if obj.cmin-1 < rt {
						rt = obj.cmin - 1
					}
				}
			}
			u_intervals = append(u_intervals, Interval{st, en, lt, rt})
		}
	}

	d_points := make([]int, 0, len(OL)+len(OR)+2)
	d_points = append(d_points, R2, D_max+1)
	for _, obj := range OL {
		if obj.rmin > R2 && obj.rmin <= D_max {
			d_points = append(d_points, obj.rmin)
		}
	}
	for _, obj := range OR {
		if obj.rmin > R2 && obj.rmin <= D_max {
			d_points = append(d_points, obj.rmin)
		}
	}
	d_points = uniqueSort(d_points)

	d_intervals := make([]Interval, 0, len(d_points))
	for i := 0; i < len(d_points)-1; i++ {
		st := d_points[i]
		en := d_points[i+1] - 1
		if st <= en {
			lb := L_always
			rb := R_always
			for _, obj := range OL {
				if obj.rmin > R2 && st >= obj.rmin {
					if obj.cmax+1 > lb {
						lb = obj.cmax + 1
					}
				}
			}
			for _, obj := range OR {
				if obj.rmin > R2 && st >= obj.rmin {
					if obj.cmin-1 < rb {
						rb = obj.cmin - 1
					}
				}
			}
			d_intervals = append(d_intervals, Interval{st, en, lb, rb})
		}
	}

	ans := int64(0)
	for _, ui := range u_intervals {
		for _, di := range d_intervals {
			L := ui.L
			if di.L > L {
				L = di.L
			}
			R := ui.R
			if di.R < R {
				R = di.R
			}

			if L <= C1 && R >= C2 {
				ans += int64(ui.end-ui.start+1) * int64(di.end-di.start+1) * int64(C1-L+1) * int64(R-C2+1)
			}
		}
	}

	return ans
}

func main() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Fscan(reader, &N, &M, &K_objs)
	if N == 0 {
		return
	}

	grid := make([]string, N)
	for i := 0; i < N; i++ {
		fmt.Fscan(reader, &grid[i])
	}

	visited := make([][]bool, N)
	for i := 0; i < N; i++ {
		visited[i] = make([]bool, M)
	}

	objs = make([]Object, 0, K_objs)
	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			if grid[i][j] == '*' && !visited[i][j] {
				r_end := i
				c_end := j
				for c_end+1 < M && grid[i][c_end+1] == '*' {
					c_end++
				}
				for r_end+1 < N && grid[r_end+1][j] == '*' {
					r_end++
				}
				for r := i; r <= r_end; r++ {
					for c := j; c <= c_end; c++ {
						visited[r][c] = true
					}
				}
				objs = append(objs, Object{i + 1, r_end + 1, j + 1, c_end + 1})
			}
		}
	}

	total_ans := int64(0)
	K := len(objs)

	for i := 0; i < K; i++ {
		total_ans += solve([]int{i})
	}

	for i := 0; i < K; i++ {
		for j := i + 1; j < K; j++ {
			total_ans += solve([]int{i, j})
		}
	}

	for i := 0; i < K; i++ {
		for j := i + 1; j < K; j++ {
			for k := j + 1; k < K; k++ {
				total_ans += solve([]int{i, j, k})
			}
		}
	}

	fmt.Println(total_ans)
}