DFS elementary algorithm exercise POJ2488 POJ3009 POJ1088

Basic exercise of depth first algorithm

1,POJ 2488

Give the size of an international chessboard, judge whether the horse can walk through the possessive lattice without repetition, and record the first path in dictionary order.

package knights_journey;

import java.util.Stack;

/**
 * @Author jinjun99
 * @Date Created in 2021/11/20 15:32
 * @Description
 * @Since version-1.0
 */
public class Demo {
    private static int n = 6;
    /**
     * checkerboard
     */
    private static int[][] cb = new int[n][n];
    /**
     * direction
     */
    private static int[][] dir = {{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}};
    private static Stack<Integer[]> currPath = new Stack<>();
    private static Stack<Integer[]> finalPath = new Stack<>();
    private static int end = 0;
    private static void dfs(int a,int b){
        if (currPath.size()==n*n){
            finalPath = (Stack<Integer[]>) currPath.clone();
            end =1;
            return ;
        }
        for (int i = 0; i < 8 && end ==0; i++) {
            int q = a+dir[i][0];
            int p = b+dir[i][1];
            if (q<n && q>-1 && p<n && p>-1 && cb[q][p]==0){
                cb[q][p] = 1;
                currPath.push(new Integer[]{q,p});
                dfs(q,p);
                cb[q][p] = 0;
                currPath.pop();
            }
        }
    }
    public static void main(String[] args) {
        cb[2][1] = 1;
        currPath.push(new Integer[]{2,1});
        dfs(2,1);
        int[][] path = new int[n][n];
        path[2][1] = 1;
        for (int i = n*n; i > 0; i--) {
            Integer[] a = finalPath.pop();
            int p = (int)a[0];
            int q = (int)a[1];
            path[p][q] = i;
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (path[i][j]<10){
                    System.out.print(" "+path[i][j]+" ");
                }else {
                    System.out.print(path[i][j]+" ");
                }

                if (j==n-1){
                    System.out.println();
                }
            }
        }
    }
}
/*Output:
 2  5 16 13 36 25 
 7 12  3 26 17 14 
 4  1  6 15 24 35 
11  8 31 20 27 18 
32 21 10 29 34 23 
 9 30 33 22 19 28  */

2,POJ 3009

Meaning: it is required to move a curler from the starting point "2" to the end point "3" with the least steps, where 0 is the moving area and 1 is the stone area. Once the curler thinks about a certain direction, the movement will not stop or change the direction (think about the curler sliding on the ice), unless the curler hits stone 1 or reaches the end point 3. After the curler hits the stone, the curler will stop in front of the stone, At this time (static state), it is allowed to change the movement direction of the curler, and the stone will break, and the area where the stone is located will change from 1 to 0, that is, after the curler hits the stone, it will not replace the position of the stone. The end point is an area with great friction. If the curler reaches the end point 3, it will stop moving at the end point. Curling will fail if it moves more than 10 or touches the wall at a single time.

package curling;

import java.util.Stack;

/**
 * @Author jinjun99
 * @Date Created in 2021/11/20 19:47
 * @Description
 * @Since version-1.0
 */
public class Deom01 {
    private static int n = 8;
    private static int[][] map = {
            {2,0,0,1,0,0,0,0},
            {0,0,0,1,0,1,0,0},
            {0,1,1,1,0,1,0,0},
            {0,0,0,0,0,0,0,1},
            {1,1,1,1,1,1,0,0},
            {0,0,0,0,0,0,0,0},
            {0,0,1,1,1,1,3,1},
            {0,0,0,0,0,0,0,0},};
    private static int[] dirX = {0,1,0,-1};
    private static int[] dirY = {1,0,-1,0};

    private static int currStep = 0;
    private static int minStep = 0;
    public static void main(String[] args) {
        map[0][0] = 2;
        map[6][7] = 3;
        dfs(0,0);
        System.out.println("The minimum number of steps is:"+minStep);
    }
    private static void dfs(int x, int y){

        for (int i = 0; i < 4; i++) {
            int a = x;
            int b = y;
            for (int j = 0; j <10; j++) {
                a+=dirX[i];
                b+=dirY[i];
                if (a<0||a>=n||b<0||b>=n){
                    break;
                }
                if (map[a][b]==3){
                    currStep+=(j+1);
                    if (currStep<minStep||minStep==0){
                        minStep = currStep;
                    }
                    currStep-=(j+1);
                    break;
                }
                if (map[a][b]==1){
                    currStep+=j;
                    map[a][b]=0;
                    dfs(a-dirX[i],b-dirY[i]);
                    currStep-=j;
                    map[a][b]=1;
                    break;
                }
            }
        }
    }
}
/*Minimum steps: 12*/

3,POJ 1088

It's not surprising that Michael likes skiing, because skiing is really exciting. However, in order to get speed, the sliding area must tilt downward, and when you slide to the bottom of the slope, you have to go up the slope again or wait for the elevator to pick you up. Michael wants to know the longest bottom landslide in an area. The region is given by a two-dimensional array. Each number in the array represents the height of the point. Here is an example
1 2 3 4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

A person can slide up and down from a certain point to one of the four adjacent points on the left and right if and only if the height decreases. In the above example, a sliding landslide is 24-17-16-1. Of course, 25-24-23 -... - 3-2-1 is longer. In fact, this is the longest one.

package skiing;

import java.util.Stack;

/**
 * @Author jinjun99
 * @Date Created in 2021/11/19 21:37
 * @Description
 * @Since version-1.0
 */
public class Demo02 {
    private static int r = 5;
    private static int c = 5;
    private static int[][] heightMap = {
            {1 , 2, 3, 4, 5},
            {16,17,18,19, 6},
            {15,24,25,20, 7},
            {14,23,22,21, 8},
            {13,12,11,10, 9}};
    
    private static Stack<Integer> currPath = new Stack<>();
    private static Stack<Integer> shortestPath = new Stack<>();

    public static void main(String[] args) {

        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                backTrack(i,j);
            }
        }
        System.out.println("Maximum length:"+shortestPath.size());
        System.out.println("Longest path:");
        System.out.println(shortestPath);

    }

    private static void backTrack(int i,int j){
        currPath.push(heightMap[i][j]);

        int b=1;
        if (i<r-1&&heightMap[i+1][j]<heightMap[i][j]){
            backTrack(i+1,j);
            b=0;
        }

        if (i>0&&heightMap[i-1][j]<heightMap[i][j]){
            backTrack(i-1,j);
            b=0;
        }
        if (j<c-1&&heightMap[i][j+1]<heightMap[i][j]){
            backTrack(i,j+1);
            b=0;
        }
        if (j>0&&heightMap[i][j-1]<heightMap[i][j]){
            backTrack(i,j-1);
            b=0;
        }

        if (b==1&&currPath.size()>shortestPath.size()){
            shortestPath = (Stack<Integer>) currPath.clone();
        }
        currPath.pop();
    }
}
/*
Maximum length: 25
 Longest path:
[25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
*/

4. Maze problem

Use a two-dimensional array to represent the maze, 1 represents obstacles, 0 represents passable, and then ask how many paths can go to the end from beginning to end. The same problem is dfs plus backtracking, which is to traverse the upper, lower, left and right directions of each passing point until you finally reach the end, and then backtrack again is return 1, which restores the passing path to 0 (because the passing paths are marked as 1), Finally, return sum outputs the results that can be returned.

Map:

0 0 0 1 0 0 0 0
0 0 0 1 0 1 0 0
0 1 1 1 0 1 0 0
0 0 0 0 0 1 0 0
1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1
0 0 0 0 0 0 0 0
package maze;
/**
 * @Author jinjun99
 * @Date Created in 2021/11/20 10:38
 * @Description Find out how many paths the maze has from the beginning to the end
 * @Since version-1.0
 */
public class Demo02 {
    //Number of labyrinth rows and columns
    private static int n = 8;
    //maze 
    private static int[][] maze = {
            {0,0,0,1,0,0,0,0},
            {0,0,0,1,0,1,0,0},
            {0,1,1,1,0,1,0,0},
            {0,0,0,0,0,1,0,0},
            {1,1,1,1,1,1,0,0},
            {0,0,0,0,0,0,0,0},
            {0,0,1,1,1,1,1,1},
            {0,0,0,0,0,0,0,0},};
    //Mark the position you have passed
    private static int[][] sign = new int[n][n];
    private static int dfs(int x,int y){
        //If you cross the boundary, hit a wall or have passed, return 0
        if (x==n||x<0||y==n||y<0||sign[x][y]==1||maze[x][y]==1){
            return 0;
        }
        //If you reach the end, return to 1
        if (x==n-1&&y==n-1){
            return 1;
        }
        //Mark points passed
        sign[x][y]=1;
        int count = 0;
        count += dfs(x+1,y);
        count += dfs(x-1,y);
        count += dfs(x,y+1);
        count += dfs(x,y-1);
        //to flash back
        sign[x][y]=0;
        return count;
    }

    public static void main(String[] args) {
        int sum = dfs(0,0);
        System.out.println("Number of paths:"+sum);
    }
}
/*Number of paths: 384*/

Posted on Wed, 24 Nov 2021 01:12:16 -0500 by rallokkcaz