• 蓝桥杯_连通性


    一、完整代码:

    import util.*;
    public class Main {
    	static boolean dfs(char[][] map, int y1, int x1, int y2, int x2) {
    		if(y1 == y2 && x1 == x2) return true;
    		char old = map[y1][x1];
    		map[y1][x1] = "*";
    		try {
    			if(y1 > 0 && map[y1-1][x1] == old && dfs(y1-1, x1, y2, x2)) return true;
    			if(y1 < map.length-1 && map[y1+1][x1] == old && dfs(y1+1, x1, y2, x2)) return true;
    			if(x1 > 0 && map[y1][x1-1] == old && dfs(y1, x1-1, y2, x2)) return true;
    			if(x1 < map.length-1 && map[y1][x1+1] && dfs(y1, x1+1, y2, x2)) return true;
    		}
    		finally {
    			map[y1][x2] = old;
    		}
    		return false;
    	}
    	public static void main(String[] args) {
    		Scanner cin = new Scanner(System.in);
    		int n = cin.nextInt();
    		char[][] map = new char[n][];
    		for(int i = 0; i < n; i++) {
    			map[i] = cin.nextLine().toCharArray();
    		}
    
    		int m = cin.nextInt();
    		for(int i = 0; i < m; i++) {
    			String[] temp = cin.nextLine.split(" ");
    			int y1 = Integer.parseInt(temp[0]);
    			int x1 = Integer.parseInt(temp[1]);
    			int y2 = Integer.parseInt(temp[2]);
    			int x2 = Integer.parseInt(temp[3]);
    			boolean ans = dfs(y1, x1, y2, x2);
    			System.out.println(ans);
    		}
    	}
    }
    

    二、处理输入

    1、对地图的处理

    地图是这样输入的:

    0010000000
    0011100000
    0000111110
    0001100010
    1111010010
    0000010010
    0000010011
    0111111000
    0000010000
    0000000000

    因为我们这里的输入比较紧密,没有被空格分隔,

    所以可以利用String类中的toCharArray()方法,该方法可以自动将字符分割开来,还是挺好用的

    char[][] map = new char[n][];
    for(int i = 0; i < n; i++) {
        map[i] = cin.nextLine().toCharArray();
    }
    

    2、对输入的起始位置的处理

    每组输入是这样输入的:

    0 0 9 9
    0 2 6 8
    4 4 4 6

    这里就是很普通的切割被空格分割的字符串:

    1. 先用String类的split()方法,字符数组变得紧凑
    2. 然后强转成int
    for(int i = 0; i < m; i++) {
        String temp = cin.nextLine().split(" ");
        int y1 = Integer.parseInt(temp[0]);
        int x1 = Integer.parseInt(temp[1]);
        int y2 = Integer.parseInt(temp[2]);
        int x2 = Integer.parseInt(temp[3]);
        boolean ans = dfs(map, y1, x1, y2, x2);
        System.out.println(ans);
    }
    

    三、dfs

    接下来是dfs,这里是boolean型的dfs,以前很少用到,可以值得好好解析一下。

    1、递归出口

    if(y1 == y2 && x1 == x2) return true;
    

    如果一开始输入的起始位置相同,那么肯定可以搜索到。

    更常见的情况是,随着下面的搜索循环体的dfs,(y1,x1)会不断移动,如果能够正好移动到(y2,x2),那就说明连通了。

    2、dfs循环体

    接下来,就是对上下左右四个方向进行dfs

    比如向左方搜索:

    if(y1 > 0 && map[y1][x1] == old && dfs(map, y1-1, x1, y2, x2)) return true;
    

    这个和一般的dfs并没有什么不同,只不过是boolean型的

    3、保护现场与恢复

    char old = map[y1][x1];	//将起点的符号记录下来
    map[y1][x1] = "*";	//标记为此时已经搜索过
    try {
        ...	//dfs循环体
    }
    finally {
        map[y][x1] = old;	//恢复现场
    }
    return false;
    

    首先,我们需要判断的起始点对是很多组的,判断完毕一组之后,要将一切恢复到原来的样子,否则下一组怎么用呢?

  • 相关阅读:
    Find the Longest Word in a String
    Check for Palindromes
    Factorialize a Number
    Reverse a String
    Java中的线程概念
    websocket 实现实时消息推送
    linux安装tomcat, jdk出现的问题
    JSON, list, 前台显示
    数据库NULL和 ‘’ 区别
    js获取后台json数据显示在jsp页面元素
  • 原文地址:https://www.cnblogs.com/huangming-zzz/p/10560389.html
Copyright © 2020-2023  润新知