洛谷P1141 Java解法

题目出处点这里
在这里插入图片描述
思路①:对每一个m点进行广搜,输出搜到的结果即可
思路②:很明显思路①会MLE或TLE,我们发现有可能多个m点会在同一个区域(这里的区域指前面的m点搜过的区域),如果再次搜索无疑会造成大量时间的浪费,因此我们可以标记每一次搜过的区域为已访问并用另一个二维数组temp[ ][ ]把该区域的所有点的值赋值为相应可以走到的格数即可,并在每次输入m点时判断此点是否被访问过,如果被访问过就直接输出temp里相应点的值即可,如果没有被访问过就对该点广搜即可。不过要注意读入方式和输出方式,适当的方法会节省不少时间。

代码:

package search;

import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.LinkedList;
import java.util.Queue;

public class P1141 {

	static int n, m, temp[][];
	static int[] xx = { 0, 0, 1, -1 };
	static int[] yy = { 1, -1, 0, 0 };
	static boolean[][] vis;
	static char[][] arr;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StreamTokenizer st = new StreamTokenizer(br);
		PrintWriter pw = new PrintWriter(System.out);
		st.nextToken();
		n = (int)st.nval;
		st.nextToken();
		m = (int)st.nval;
		arr = new char[n][n];
		temp = new int[n][n];
		vis = new boolean[n][n];
		br.readLine();
		for (int i = 0; i < n; i++) {
			arr[i] = br.readLine().toCharArray();
		}
		for (int i = 0; i < m; i++) {
			st.nextToken();
			int x = (int)st.nval;
			st.nextToken();
			int y = (int)st.nval;
			if (!vis[x - 1][y - 1]) {
				bfs(x - 1, y - 1, 1);
			}
			pw.println(temp[x - 1][y - 1]);
		}
		pw.flush();
	}

	public static void bfs(int x, int y, int sum) {
		Queue<Point> q = new LinkedList<Point>();
		Queue<Point> t = new LinkedList<Point>();
		q.add(new Point(x, y));
		t.add(new Point(x, y));
		vis[x][y] = true;
		while (!q.isEmpty()) {
			Point p = q.poll();
			for (int i = 0; i < 4; i++) {
				int row = p.x + xx[i];
				int col = p.y + yy[i];
				if (row >= 0 && row < n && col >= 0 && col < n && !vis[row][col]) {// 首先要确保能走
					if (arr[row][col] == '1' && arr[p.x][p.y] == '0') {// 第一种情况是当前点为0,下一步点为1
						q.add(new Point(row, col));
						t.add(new Point(row, col));
						vis[row][col] = true;// 置为已访问过
						sum++;// ++
					}
					if (arr[row][col] == '0' && arr[p.x][p.y] == '1' && !vis[row][col]) {// 第二种情况是当前点为1,下一步点为0
						q.add(new Point(row, col));
						t.add(new Point(row, col));
						vis[row][col] = true;// 置为已访问过
						sum++;// ++
					}
				}
			}
		}
		while (!t.isEmpty()) {
			Point p = t.poll();
			temp[p.x][p.y] = sum;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/TXXERIN/article/details/107661073