https://www.acmicpc.net/problem/17135
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.StringTokenizer;
public class Main {
static int N, M, D, answer;
static int[][] board;
static LinkedList<Point> bowLoc;
static ArrayList<Point> enemyLoc, tempLoc;
static void input() {
Reader scanner = new Reader();
N = scanner.nextInt();
M = scanner.nextInt();
D = scanner.nextInt();
board = new int[N + 1][M];
bowLoc = new LinkedList<>();
enemyLoc = new ArrayList<>();
tempLoc = new ArrayList<>();
for(int row = 0; row < N; row++) {
for(int col = 0; col < M; col++) {
board[row][col] = scanner.nextInt();
if(board[row][col] == 1) {
enemyLoc.add(new Point(row, col));
tempLoc.add(new Point(row, col));
}
}
}
}
static void solution() {
answer = 0;
int[][] copy = new int[N + 1][M];
for(int row = 0; row < copy.length; row++) copy[row] = board[row].clone();
selectBow(0, 0);
System.out.println(answer);
}
static void selectBow(int index, int size) {
if(size == 3) {
int removedNum = simulate();
answer = Math.max(answer, removedNum);
tempLoc = new ArrayList<>();
for(Point p : enemyLoc) tempLoc.add(new Point(p.x, p.y));
return;
}
for(int idx = index; idx < M; idx++) {
board[N][idx] = 2;
bowLoc.add(new Point(N, idx));
selectBow(idx, size + 1);
bowLoc.remove(bowLoc.size() - 1);
board[N][idx] = 0;
}
}
static int simulate() {
int total = 0;
HashSet<Point> set = null;
while(true) {
if(tempLoc.size() == 0) break;
set = new HashSet<>();
for(Point bLoc : bowLoc) {
PriorityQueue<Point> queue = new PriorityQueue<Point>(new Comparator<Point>() {
public int compare(Point p1, Point p2) {
int dist1 = Math.abs(bLoc.x - p1.x) + Math.abs(bLoc.y - p1.y);
int dist2 = Math.abs(bLoc.x - p2.x) + Math.abs(bLoc.y - p2.y);
if(dist1 != dist2) return dist1 - dist2;
return p1.y - p2.y;
}
});
for(Point eLoc : tempLoc) {
if(Math.abs(bLoc.x - eLoc.x) + Math.abs(bLoc.y - eLoc.y) <= D) {
queue.offer(eLoc);
}
}
Point attacked = queue.poll();
if(attacked != null) set.add(attacked);
}
ArrayList<Point> newLoc = new ArrayList<>();
for(int idx = 0; idx < tempLoc.size(); idx++) {
if(set.contains(tempLoc.get(idx))) continue;
else {
Point enemy = tempLoc.get(idx);
if(enemy.x + 1 >= N) continue;
newLoc.add(new Point(enemy.x + 1, enemy.y));
}
}
tempLoc = newLoc;
total += set.size();
}
return total;
}
static class Point {
int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object obj) {
Point p = (Point)obj;
if(this.x == p.x && this.y == p.y) return true;
return false;
}
public int hashCode() {
return Objects.hash(x, y);
}
}
public static void main(String[] args) {
input();
solution();
}
static class Reader {
BufferedReader br;
StringTokenizer st;
public Reader() {
br = new BufferedReader(new InputStreamReader(System.in));
}
String next() {
while(st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch(IOException e) {
e.printStackTrace();
}
}
return st.nextToken();
}
int nextInt() {
return Integer.parseInt(next());
}
}
}