Kattis Problem - Prozor
题目类型:枚举、二维前缀和
题意
有一个 R x S 大小的矩形窗户,在窗户上趴着一些苍蝇,现在有一个边长为 K 的正方形苍蝇拍,求拍一次所能攻击到的苍蝇的最大数量(苍蝇拍一定是拍在窗户内部,且边界处的苍蝇是可以逃走的所以不计数),在窗户中 ‘*’ 代表苍蝇 ‘.’ 代表空白。
分析
因为边界处的苍蝇不计数,所以枚举所有 边长为 k - 1 的正方形中苍蝇的数量然后取最大值,枚举所有正方形可以通过预处理矩形的二维前缀和优化。具体细节参考代码。
代码
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;
public class Main {
static final int MAX_N = 100010;
static final int INF = 0x3f3f3f3f;
static final int mod = 1000000007;
public static void main(String[] args) throws IOException {
initReader(System.in);
solve();
printWriter.flush();
}
/*******************************************************************************************************************************/
static char[][] G;
static int[][] a;
static int[][] pre;
public static void solve() throws IOException {
int R = nextInt();
int S = nextInt();
int k = nextInt();
G = new char[R + 10][S + 10];
a = new int[R + 10][S + 10];
pre = new int[R + 10][S + 10];
for (int i = 1; i <= R; i++) {
String s = next();
for (int j = 1; j <= S; j++) {
G[i][j] = s.charAt(j - 1);
if (G[i][j] == '*') {
a[i][j] = 1;
}
}
}
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= S; j++) {
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + a[i][j];
}
}
int x = 0, y = 0, Max = 0;
for (int i = k - 1; i < R; i++) {
for (int j = k - 1; j < S; j++) {
int x1 = i - (k - 3), y1 = j - (k - 3);
int x2 = i, y2 = j;
int re = pre[x2][y2] - pre[x1 - 1][y2] - pre[x2][y1 - 1] + pre[x1 - 1][y1 - 1];
if (Max < re) {
Max = re;
x = x2 + 1;
y = y2 + 1;
}
}
}
int xx, yy;
xx = x - (k - 1);
yy = y - (k - 1);
G[xx][yy] = '+';
G[xx][y] = '+';
G[x][yy] = '+';
G[x][y] = '+';
for (int i = 1; i <= k - 2; i++) {
G[xx][yy + i] = '-';
G[x][yy + i] = '-';
G[xx + i][yy] = '|';
G[xx + i][y] = '|';
}
printWriter.println(Max);
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= S; j++) {
printWriter.print(G[i][j]);
}
printWriter.println();
}
}
/*******************************************************************************************************************************/
static BufferedReader reader;
static StringTokenizer tokenizer;
static PrintWriter printWriter;
public static void initReader(InputStream input) throws IOException {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
}
public static boolean hasNext() {
try {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
} catch (Exception e) {
return false;
}
return true;
}
public static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
public static String nextLine() {
try {
return reader.readLine();
} catch (Exception e) {
return null;
}
}
public static int nextInt() throws IOException {
return Integer.parseInt(next());
}
public static long nextLong() throws IOException {
return Long.parseLong(next());
}
public static double nextDouble() throws IOException {
return Double.parseDouble(next());
}
public static char nextChar() throws IOException {
return next().charAt(0);
}
}