在N*M的草地上,提莫种了K个蘑菇,蘑菇爆炸的威力极大,兰博不想贸然去闯,而且蘑菇是隐形的.只
有一种叫做扫描透镜的物品可以扫描出隐形的蘑菇,于是他回了一趟战争学院,买了2个扫描透镜,一个
扫描透镜可以扫描出(3*3)方格中所有的蘑菇,然后兰博就可以清理掉一些隐形的蘑菇. 问:兰博最多可以清理多少个蘑菇?
注意:每个方格被扫描一次只能清除掉一个蘑菇。
第一行三个整数:N,M,K,(1≤N,M≤20,K≤100),N,M代表了草地的大小; 接下来K行,每行两个整数x,y(1≤x≤N,1≤y≤M).代表(x,y)处提莫种了一个蘑菇. 一个方格可以种无穷个蘑菇.
输出一行,在这一行输出一个整数,代表兰博最多可以清理多少个蘑菇.
缺少前提条件:一次只能清除一个方格里头的一个蘑菇,而不是所有!!!!(浪费了我半个多小时来检查问题) import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class Main { public static int LENGTH = 2; public static void main(String[] args) throws FileNotFoundException { int N = 0, M = 0, K; Scanner scanner = new Scanner(System.in); while (scanner.hasNext()) { // 1.输入数据 N = scanner.nextInt(); M = scanner.nextInt(); K = scanner.nextInt(); int[][] num = new int[N][M];// 蘑菇分布 while (K > 0) { int x = scanner.nextInt() - 1; int y = scanner.nextInt() - 1; if (x < N && y < M) { num[x][y]++; K--; } } // 2.统计个数 Point firstPoint = findMaxNum(N, M, num); clear(firstPoint, num, N, M); Point secondPoint = findMaxNum(N, M, num); System.out.println(firstPoint.count + secondPoint.count); } } // x,y public static Point getNumInLocation(int N, int M, int[][] num, int startX, int startY) { int endX, endY; // 1.确定区域 if (startX + LENGTH > N - 1) { endX = N - 1; } else { endX = startX + LENGTH; } if (startY + LENGTH > M - 1) { endY = M - 1; } else { endY = startY + LENGTH; } // 2.统计个数 Point point = new Main().new Point(); point.count = 0; point.x = startX; point.y = startY; point.endX = endX; point.endY = endY; for (int i = startX; i <= endX; i++) { for (int j = startY; j <= endY; j++) { if (num[i][j] > 0) { point.count++; } } } return point; } // 统计能扫描到的最大值 private static Point findMaxNum(int N, int M, int[][] num) { Point point = new Main().new Point(); point.count = 0; point.x = 0; point.y = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { Point tempPoint = getNumInLocation(N, M, num, i, j); if (point.count < tempPoint.count) { point = tempPoint; } } } return point; } // 第一次扫描完 进行清除操作 private static void clear(Point point, int[][] num, int N, int M) { for (int i = point.x; i <= point.endX; i++) { for (int j = point.y; j <= point.endY; j++) { if (num[i][j] > 0 && i < N & j < M) { num[i][j]--; } } } } class Point { int x;// 起始坐标 int y;// 起始坐标 int count;// 区域内总数 int endX;// 结束坐标 int endY;// 结束坐标 } }
如上图所示,第1次扫描的最大结果是6,但是最大值位置有3个,若选择第1次清除最中间的6个蘑菇,则第2次扫描最大结果只有3。即局部最优解并不是全局最优解。第1次选择左侧的6个蘑菇,第2次选择右侧的6个蘑菇,则全局最优解为12。
针对上述描述的易错点,在第1次扫描时候除了保存最大值外,还应该保存最大值的位置。第2次扫描的最大结果要建立在第1次扫描结果位置的基础上。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int cover9(vector<vector<int>> &mush, int row, int col) {
int count = 0;
for (int i = row - 1; i<row + 2; i++) {
for (int j = col - 1; j<col + 2; j++) {
if (mush[i][j] != 0) {
count += 1;
}
}
}
return count;
}
vector<vector<int>> searchMax(vector<vector<int>> &mush, int N, int M) {
vector<vector<int>> res(N+2, vector<int>(M+2, 0));
int temp = 0;
int maxCount = -1;
for (int i = 1; i<=N; i++) {
for (int j = 1; j<=M; j++) {
temp = cover9(mush, i, j);
if (temp > maxCount) {
res.clear();
res.resize(N + 2, vector<int>(M + 2,0));
maxCount = temp;
res[i][j] = maxCount;
}
if (temp == maxCount) {
res[i][j] = maxCount;
}
}
}
return res;
}
int removeSearch(int N,int M,int row,int col,vector<vector<int>> mush) {
for (int i = row - 1; i<row + 2; i++) {
for (int j = col - 1; j<col + 2; j++) {
mush[i][j] = (mush[i][j] == 0) ? 0 : mush[i][j] - 1;
}
}
int temp = 0;
int maxCount = -1;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
temp = cover9(mush, i, j);
if (temp >= maxCount) {
maxCount = temp;
}
}
}
return maxCount;
}
int main() {
int N, M, K;
int tempX, tempY;
while (cin >> N >> M >> K) {
vector<vector<int>> mush(N+2, vector<int>(M+2, 0));
for (int i = 0; i<K; i++) {
cin >> tempX;
cin >> tempY;
mush[tempX][tempY] += 1;
}
int res1;
int res2 = -1;
vector<vector<int>> max1 = searchMax(mush, N, M);
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) {
if (max1[i][j] != 0) {
res1 = max1[i][j];
//移除该区域的蘑菇,并进行第2次搜索
res2 = max(res2,removeSearch(N,M,i, j, mush));
}
}
}
cout <<res1+res2 << endl;
}
return 0;
}
def scanMap(arr): row = len(arr) col = len(arr[0]) most = 0 x = 0 y = 0 if row >=3: label = 3 rowrange = row-2 else: label = row rowrange = 1 if col >= 3: label2 =3 colrange = col-2 else: label2 = col colrange = 1 for i in range(rowrange): for j in range(colrange): num = 0 for m in range(label): for n in range(label2): if arr[i+m][j+n] > 0: num += 1 if num > most: most = num x = i y = j for i in range(x, x+label): for j in range(y,y+label2): if arr[i][j] > 0: arr[i][j] -= 1 return most, arr while(1): try: line = [int(x) for x in raw_input().split()] N = line[0] M = line[1] K = line[2] arr = [[0 for i in range(M)] for j in range(N)] for i in range(K): locate = [int(x) for x in raw_input().split()] arr[locate[0]-1][locate[1]-1] += 1 get = 0 most, arr = scanMap(arr) get += most most, arr = scanMap(arr) get += most print(get) except: exit(0)
#include<iostream>#include<vector>#include<algorithm>using namespace std;int main(){int N, M, K;while(cin >> N >> M >> K) {if(N < 3)N = 3;if(M < 3)M = 3;vector<vector<int>> grand1(N, vector<int>(M, 0));vector<vector<int>> grand2;int result = 0;int i, j;int first = 0, second = 0;while(K-- > 0) {cin >> i >> j;++grand1[i - 1][j - 1];}grand2 = grand1;for(int i = 0; i < N - 2; ++i)for(int j = 0; j < M - 2; ++j) {grand2 = grand1;first = 0;for(int m = i; m < i + 3; ++m) {for(int n = j; n < j + 3; ++n) {if(grand2[m][n] > 0) {++first;--grand2[m][n];}}}for(int o = 0; o < N - 2; ++o)for(int p = 0; p < M - 2; ++p) {second = 0;for(int e = o; e < o + 3; ++e)for(int f = p; f < p + 3; ++f) {if(grand2[e][f] > 0)++second;}result = max(result, first + second);}}cout << result << endl;}return 0;}
#include<iostream> using namespace std; int x,y,m,n,xx,yy; int MAX(int aa[21][21]){ int i,j,temp = 0,temp1=0,max = 0; for(i=1;i<=3;i++){//初始temp为地图前3行前3列的可扫蘑菇数。 for(j=1;j<=3;j++) if(aa[i][j] > 0) temp ++; } temp1 = temp; for(i=3;i<=n;i++){ for(j=3;j<=m;j++){ if(j>3) temp1 = temp1 - aa[i-2][j-3] - aa[i-1][j-3] - aa[i][j-3] + aa[i-2][j] + aa[i-1][j] + aa[i][j]; if(temp1 > max){ max = temp1; x = i; y = j; } } temp1 = temp; temp1 = temp1 - aa[i-2][1] - aa[i-2][2] - aa[i-2][3] + aa[i+1][1] + aa[i+1][2] + aa[i+1][3]; temp = temp1; } xx = x; yy = y; return(max); } int main(){ int k,i,j; while( cin >> n >> m >> k){ int aa[21][21]={0},bb[21][21]={0},x,y,temp1=0,temp = 0,max=0,nextmax=0; for(i=0;i<k;i++){ cin >> x >> y; aa[x][y] = 1; bb[x][y] ++; } int k = MAX(aa); for(i=xx-2;i<=xx;i++){//处理数组bb,bb为删除第一轮蘑菇后的地图 for(j=yy-2;j<=yy;j++) if(bb[i][j] > 0) bb[i][j]--; } for(i=1;i<=n;i++){ for(j=1;j<=m;j++) if( bb[i][j]>0) bb[i][j] = 1; } cout << MAX(aa) + MAX(bb) <<endl; } return 0; }
// 不能分成两步进行贪心 // 我直接对所有两步后的结果遍历 #include <stdio.h> int main() { int N, M, K, x, y, u, v; int max; int dx[] = { -1, -1, -1, 1, 1, 1, 0, 0, 0 }, dy[] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 }; while (scanf("%d %d %d", &N, &M, &K) != EOF) { max = 0; int map[30][30] = {0}; int one[30][30] = {0}; int two[30][30] = {0}; for (int i = 0; i < K; i++) { scanf("%d %d", &x, &y); map[x][y] += 1; } for (x = 1; x <= N; x++) { for (y = 1; y <= M; y++) { int sum0 = 0; for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) one[i][j] = 0; for (int i = 0; i < 9; i++) { int xx = x + dx[i]; int yy = y + dy[i]; if (xx >= 1 && xx <= N && yy >= 1 && yy <= M && map[xx][yy] > one[xx][yy]) { one[xx][yy] += 1; sum0 += 1; } } for (u = 1; u <= N; u++) { for (v = 1; v <= M; v++) { int sum1 = 0; for (int i = 1; i <= N; i++) for (int j = 1; j <= M; j++) two[i][j] = 0; for (int i = 0; i < 9; i++) { int uu = u + dx[i]; int vv = v + dy[i]; if (uu >= 1 && uu <= N && vv >= 1 && vv <= M && map[uu][vv] > (one[uu][vv] + two[uu][vv])) { two[uu][vv] += 1; sum1 += 1; } } if (sum0 + sum1 > max) max = sum0 + sum1; } } } } printf("%d\n", max); } return 0; }
#include <bits/stdc++.h> using namespace std; int cover9(vector<vector<int> > &a,int row,int col){ int c=0; for(int i=row-1;i<row+2;++i) for(int j=col-1;j<col+2;c+=(a[i][j++]?1:0)); return c; } int search(vector<vector<int> > &area,int N,int M){ int sum=0,tmp,x,y; for(int i=1;i<=N;++i){ for(int j=1;j<=M;++j){ tmp = cover9(area,i,j); if (tmp > sum){ sum=tmp; x=i,y=j; } } } for(int i=x-1;i<x+2;++i) for(int j=y-1;j<y+2;++j) area[i][j]=(area[i][j]?area[i][j]-1:0); return sum; } int main(){ for(int N,M,K;cin>>N>>M>>K;){ vector<vector<int> > area(N+2,vector<int>(M+2,0)); for(int x,y;K-- && cin>>x>>y;++area[x][y]); cout<<search(area,N,M)+search(area,N,M)<<endl; } return 0; }
基本思路,先找出第一次最大的,然后清除,再找出最大的,两次之和即为最多清除的。 但是有个陷阱或者说是我们读题目不仔细,就是每个空格可能会有多个蘑菇,而我们每次只能 清除一个蘑菇,所以每次遍历时的最大的应该是多少个方格里面有蘑菇(即数量大于0),这样 找出来的才是清除最大的,找出来之后当然是要将这些方格里面有蘑菇的都减1.然后再找一次最大的 public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(new BufferedReader(new InputStreamReader(System.in))); int N = 0; int M = 0; int K = 0; while (scanner.hasNext()) { N = scanner.nextInt(); M = scanner.nextInt(); K = scanner.nextInt(); if (N < 1 || N > 20) return; if (M < 1 || M > 20) return; if (K < 0 || K > 100) return; int[][] land = new int[M + 1][N + 1]; int x = 0, y = 0; for (int i = 0; i < K; i++) { x = scanner.nextInt(); y = scanner.nextInt(); land[y][x]++; } int max = 0, secondmax = 0; max = findMaxIn(land); secondmax = findMaxIn(land); System.out.println(max + secondmax); } } private static int findMaxIn(int[][] land) { int max = 0; int maxX = 0, maxY = 0; int num = 0; for (int i = 1; i < land.length - 1; i++) { for (int j = 1; j < land[0].length - 1; j++) { for (int k = i-1; k <=i+1; k++) { for (int m = j-1; m <=j+1; m++) { if(land[k][m]>0) num++; } } if (num > max) { max = num; maxX = j; maxY = i; } num = 0; } } for (int i = maxY - 1; i <= maxY + 1; i++) { for (int j = maxX - 1; j <= maxX + 1; j++) { if (land[i][j] > 0) land[i][j]=land[i][j]-1; } } return max; } }
答案错误:您提交的程序没有通过所有的测试用例 测试用例: 14 8 47 11 5 7 2 1 1 12 4 8 7 13 2 6 5 4 5 1 5 5 3 4 1 5 3 7 8 3 3 4 3 3 7 5 2 10 8 11 7 1 7 11 6 12 8 13 2 2 8 10 2 12 4 10 2 1 5 5 8 12 5 10 8 4 5 1 6 8 6 10 3 4 8 8 2 3 4 14 8 4 8 12 8 11 6 12 1 10 3 5 2 8 1 6 6 对应输出应该为: 9 矩阵:
#include<iostream>#include<vector>using namespace std;int main(){intn, m, k;intx, y;while(cin >> n >> m >> k){intmax = 0;inttemp1 = 0;inttemp2 = 0;if(n <= 2)n = 3;if(m <= 2)m = 3;vector<vector<int> > a(n);vector<vector<int> > b;for(inti = 0; i < n; i++)a[i].resize(m);for(inti = 0; i < n; i++)for(intj = 0; j < m; j++)a[i][j] = 0;for(inti = 0; i < k; i++){cin >> x >> y;x--;y--;a[x][y]++;}b = a;for(inti = 0; i < n - 2; i++)for(intj = 0; j < m - 2; j++){b = a;temp1 = 0;for(intp = i; p < i + 3; p++)for(intq = j; q < j + 3; q++){if(b[p][q]>0)temp1++;b[p][q]--;}for(inte = 0; e < n - 2; e++)for(intf = 0; f < m - 2; f++){temp2 = 0;for(intx = e; x < e + 3; x++)for(inty = f; y < f + 3; y++)if(b[x][y]>0)temp2 ++;if(temp1 + temp2> max)max = temp1 + temp2;}}cout << max << endl;}}搞了好久终于明白这个题的意思了。他的意思是一个方格里可以有很多个蘑菇,但是用3*3数组扫描一次只能消除每个方格里的一个蘑菇,就是说扫描一次后原方格可能还有蘑菇。我的方法是先在大数组里选取3*3数组,求出蘑菇数,然后再在当前扫描后的大数组里再选3*3数组,求取蘑菇数,再求和比较。
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line; while((line = br.readLine()) != null){ String[] params = line.split(" "); int n = Integer.parseInt(params[0]), m = Integer.parseInt(params[1]), k = Integer.parseInt(params[2]); int[][] grid = new int[n][m]; for(int i = 0; i < k; i++){ String[] pair = br.readLine().split(" "); int x = Integer.parseInt(pair[0]) - 1, y = Integer.parseInt(pair[1]) - 1; grid[x][y] = 1; } int max = 0, x = 0, y = 0; for(int i = 0; i < n - 2; i++){ for(int j = 0; j < m - 2; j++){ int temp = sum(grid, i, j); if(temp > max){ max = temp; x = i; y = j; } } } int res = max; for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ grid[x + i][y + j] = 0; } } max = 0; x = 0; y = 0; for(int i = 0; i < n - 2; i++){ for(int j = 0; j < m - 2; j++){ int temp = sum(grid, i, j); if(temp > max){ max = temp; x = i; y = j; } } } res += max; System.out.println(res); } } private static int sum(int[][] grid, int x, int y) { int res = 0; for(int i = 0; i < 3; i++){ for(int j = 0; j < 3; j++){ res += grid[x + i][y + j]; } } return res; } }
package com.special.first;
import java.util.Scanner;
/**
* 网易02-扫描透镜
*
* 我用的动态规划的思想,节省不必要的计算
* 首先求出第一个3行3列的最大值,
* 然后求第二个时候可以看做减去第一列的所有的值和加上当前的列的所有值
* 故我们每一次都保留前一次的状态
* 扩展到矩阵中,每一次起一行的时候,只需把上一行的初始3行3列值拿来直接用
* 即减去上一个9宫的第一行和加上当前的行即可
*
* 这里坑很多,注意如果格子里的蘑菇很多,只能请理一个!
* 然后我们第一次选完后,要更新这个9宫,之后再求一次最大值即可
*
* 优化:我陷入了当行列小于3的时候无法自拔,所以添加了很多无关紧要的判断代码
* 所以我们可以设置矩阵大小的时候可以跟3比较啊,小于3的时候,就申请3行3列,空白格为0
* 不影响结果!!!
* Create by Special on 2018/3/11 16:34
*/
public class Pro064 {
public static int cleanMushrooms(int N, int M, int[][] mushrooms){
int indexR = 0, indexC = 0, max = 0, begin = 0, temp = 0;
int beginRow = N >= 3 ? 3 : N;
int beginCol = M >= 3 ? 3 : M;
for(int i = 0; i < beginRow; i++){
for(int j = 0; j < beginCol; j++){
if(mushrooms[i][j] > 0) {
begin++;
}
}
}
temp = begin;
max = Math.max(max, temp);
for(int j = 3; j < M; j++){
for(int i = 0; i < beginRow; i++){
temp = temp - (mushrooms[i][j - 3] > 0 ? 1 : 0)
+ (mushrooms[i][j] > 0 ? 1 : 0);
}
if(temp > max){
max = temp;
indexR = 0;
indexC = j - 2;
}
}
for(int i = 3; i < N; i++){
for(int j = 0; j < beginCol; j++){
begin = begin - (mushrooms[i - 3][j] > 0 ? 1 : 0)
+ (mushrooms[i][j] > 0 ? 1 : 0);
}
temp = begin;
if(temp > max){
max = temp;
indexR = i - 2;
indexC = 0;
}
for(int j = 3; j < M; j++){
for(int index = i - 2; index <= i; index++) {
temp = temp - (mushrooms[index][j - 3] > 0 ? 1 : 0)
+ (mushrooms[index][j] > 0 ? 1 : 0);
}
if(temp > max){
max = temp;
indexR = i - 2;
indexC = j - 2;
}
}
}
int result = max;
for(int i = indexR; i < Math.min(N, indexR + 3); i++){
for(int j = indexC; j < Math.min(M, indexC + 3); j++){
if(mushrooms[i][j] > 0){
mushrooms[i][j]--;
}
}
}
return result;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNext()){
int N = input.nextInt();
int M = input.nextInt();
int K = input.nextInt();
int[][] mushrooms = new int[N][M];
while(K-- > 0){
mushrooms[input.nextInt() - 1][input.nextInt() - 1]++;
}
int result = 0;
result += cleanMushrooms(N, M, mushrooms);
result += cleanMushrooms(N, M, mushrooms);
System.out.println(result);
}
}
}
#include <bits/stdc++.h> using namespace std; void Scan(vector<vector<int>> G, int N, int M, int result[]) { for(int i=0;i<N-2;i++) for(int j=0;j<M-2;j++) { int t = 0; for(int p=i;p<i+3;p++) for(int q=j;q<j+3;q++) if(G[p][q]>0) t++; if(result[0]<t) { result[0] = t; result[1] = i; result[2] = j; } } } int main() { int N,M,K; int x,y; while(cin>>N>>M>>K) { if(N<3) N = 3; if(M<3) M = 3; vector<vector<int>> G(N,vector<int>(M,0)); while(K--) { cin>>x>>y; G[x-1][y-1]++; } int first[3] = {0}; int second[3] = {0}; Scan(G,N,M,first); for(int i=first[1];i<first[1]+3;i++) for(int j=first[2];j<first[2]+3;j++) if(G[i][j]>0) G[i][j]--; Scan(G,N,M,second); cout<<first[0]+second[0]<<endl; } return 0; }
//好像也只有暴力求了吧 #include<iostream> #include<vector> using namespace std; int main(){ int N, M, K; while(cin>>N>>M>>K){ vector<vector<int>> input(N, vector<int>(M, 0)); for(int i = 0; i < K; ++i){ int x, y; cin>>x>>y; input[x-1][y-1]++; } int max1 = 0, max2 = 0; int x, y; for(int i = 0; i < N-2; ++i){ for(int j = 0; j < M-2; ++j){ int num = 0; for(int t = i; t <= i+2; ++t){ for(int k = j; k <= j+2; ++k) if(input[t][k]) num++; } if(num > max1){ max1 = num; x = i; y = j; } } } for(int i = 0; i < N-2; ++i){ for(int j = 0; j < M-2; ++j){ int num = 0; for(int t = i; t <= i+2; ++t){ for(int k = j; k <= j+2; ++k){ if(t >= x && t <= x+2 && k >= y && k <= y+2){ if(input[t][k] > 1) num++; } else if(input[t][k]) num++; } } if(num > max2) max2 = num; } } cout<<max1+max2<<endl; } return 0; }
#include <iostream> using namespace std; int main(){ int N, M, K; while (cin >> N >> M >> K){ int map[30][30] = { 0 }; for (int i = 0; i < K; i++){//数据载入一个二维数组 int x, y; cin >> x >> y; map[x][y]++; } int sum = 0; int max_i = 0; int max_j = 0; for (int i = 0; i < N - 1; i++){//遍历数组,记录一次最大可消除数量 for (int j = 0; j < M - 1; j++){ int temp;//可用函数代替计算九宫格,这里直接算了 temp = !map[i][j] + !map[i + 1][j] + !map[i + 2][j] + !map[i][j + 1] + !map[i + 1][j + 1] + !map[i + 2][j + 1] + !map[i][j + 2] + !map[i + 1][j + 2] + !map[i + 2][j + 2]; temp = 9 - temp; if (temp > sum){//记录最大位置 sum = temp; max_i = i; max_j = j; } } } for (int i = max_i; i < max_i + 3; i++){ for (int j = max_j; j < max_j + 3; j++){//将第一遍消除的蘑菇减去 if(map[i][j] > 0) --map[i][j]; } } int sum2 = 0; for (int i = 0; i < N - 1; i++){//第二遍同理 for (int j = 0; j < M - 1; j++){ int temp; temp = !map[i][j] + !map[i + 1][j] + !map[i + 2][j] + !map[i][j + 1] + !map[i + 1][j + 1] + !map[i + 2][j + 1] + !map[i][j + 2] + !map[i + 1][j + 2] + !map[i + 2][j + 2]; temp = 9 - temp; if (temp > sum2) sum2 = temp; } } cout << sum + sum2 << endl; } }
// 讲真,这题目蛮神奇的,其实意思就是让你先遍历每一个点,把这个点当做(3*3)的起点开始扫描 // 统计每一个点作为起点时的9个方格中蘑菇的数目,并且保存数目,及起点的坐标,遍历完一遍后 // 将最多蘑菇数目保存,并且将最多蘑菇的起点开始,那9个点里的蘑菇数目-1,然后开始第二次扫描 import java.util.*; public class Main{ public static void main(String[] args){ Scanner in = new Scanner(System.in); while(in.hasNext()){ int N = in.nextInt(); int M = in.nextInt(); int K = in.nextInt(); int[][] mush = new int[N][M]; int cnt = 0; for(int i = 0; i < K; i++) mush[in.nextInt() - 1][in.nextInt() - 1]++; System.out.println(find(mush, N, M)); } } public static int find(int[][] mush, int N, int M){ int x = 0, y = 0, max = 0; for(int i = 0; i < N - 2; i++){ for(int j = 0; j < M - 2; j++){ int tmp = 0; for(int p = i; p < i + 3; p++){ for(int q = j; q < j + 3; q++){ if(mush[p][q] >= 1) tmp++; } } if(tmp > max){ max = tmp; x = i; y = j; } } } for(int p = x; p < x + 3; p++){ for(int q = y; q < y + 3; q++){ if(mush[p][q] >= 1) mush[p][q]--; } } int maxf = max; max = 0; for(int i = 0; i < N - 2; i++){ for(int j = 0; j < M - 2; j++){ int tmp = 0; for(int p = i; p < i + 3; p++){ for(int q = j; q < j + 3; q++){ if(mush[p][q] >= 1) tmp++; } } if(tmp > max) max = tmp; } } return maxf + max; } }