【Java】最长路径(递归回溯/深搜)

单元测验,一开始完全没思路,老师给了C++代码并讲了思路,自己改成了Java并写上了注释

题目

Description

把m * n的方地划分成m*n格,每格上标上一个整数。当相信邻的的两格数据一样或相差为1时就可以连通。请找出最长的连通路线。注意只能上下左右四个方向移动。例如:
在这里插入图片描述
的长度为21.

Input

有多个案例,每个案例先输入两个整数m、n,接着有m行n列的数。这两数在50以内。

Ouput

输出最长路径的长度。

Sample Input

5 6
1 2 3 5 5 6
2 1 3 9 8 7
4 2 1 5 6 8
1 2 3 8 7 7
1 2 3 4 5 6

Sample Output

21

代码

C++

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <queue>
using namespace std;
int a,b,c,d;
int road[500][500],flag[500][500];
int t[4][2]={
    
    {
    
    1,0},{
    
    -1,0},{
    
    0,1},{
    
    0,-1}};
int maxLen;
void dfs(int x,int y,int num)
{
    
    
	for(int n=0;n<4;n++)
	{
    
    
		int dx = x + t[n][0];
		int dy = y + t[n][1];
		if(dx>=0&&dx<a&&dy>=0&&dy<b&&flag[dx][dy]==0&&(road[x][y]-road[dx][dy]==1||road[x][y]-road[dx][dy]==-1||road[x][y]==road[dx][dy]))
		{
    
    
			flag[dx][dy]=1;
			dfs(dx,dy,num+1);
			flag[dx][dy]=0;
		}
	}
	if(num>maxLen)
	{
    
    
		maxLen = num;
	}
}
int main(int argc, char *argv[]) {
    
    
	int n,m;
	while(scanf("%d %d",&a,&b)!=EOF)
	{
    
    
		maxLen = -1;
		for(n=0;n<a;n++)
		{
    
    
			for(m=0;m<b;m++)
			{
    
    
				scanf("%d",&road[n][m]);
			}
		}
		for(n=0;n<a;n++)
		{
    
    
			for(m=0;m<b;m++)
			{
    
    
				memset(flag,0,sizeof(flag));
				flag[n][m]=1;
				dfs(n,m,1);
			}
		}
		printf("%d\n",maxLen);
	}
	return 0;
}

Java

package B最长路径;

import java.util.Scanner;

public class Main {
    
    
	/**
	 * a b 表示a行b列
	 * road表示读入的a行b列矩阵
	 * flag用来标记可以走通的路径
	 * t 表示四种移动方式:上下左右
	 * maxLen 表示最长路径
	 */
    static int a,b;
    static int[][] road,flag;
    static int[][] t = {
    
    {
    
    0,-1},{
    
    0,1},{
    
    -1,0},{
    
    1,0}};
    static int maxLen;
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);
        while(in.hasNext()) {
    
    
        	 maxLen=-1;
        	 a = in.nextInt();
        	 b = in.nextInt();
        	road = new int[a][b];
        	for(int i=0;i<a;i++)
        		for(int j=0;j<b;j++)
        			road[i][j] = in.nextInt();
        	
        	//从(i,j)开始移动
        	for(int i=0;i<a;i++)
        	{
    
    
        		for(int j=0;j<b;j++) {
    
    
        			//每次出发前将用来标记的flag初始化
        			flag = new int[a][b];
        			//标记出发点(i,j)为1
        			flag[i][j] = 1;
        			//从(i,j)开始走,这时路径长度为1
        			dfs(i,j,1);
        		}
        	}
        	System.out.println(maxLen);	
        }
       in.close();
	}
	/**
	 * @param num 计算路径长度
	 */
  public static void dfs(int x,int y,int num) {
    
    
	  //(dx,dy)表示与(x,y)相邻的点
	  for(int n=0;n<4;n++) {
    
    //有四种移动方法,回溯
		  int dx = x+t[n][0];//左右移动
		  int dy = y+t[n][1];//上下移动
		  /* 1.dx>=0 && dx<a && dy>=0 && dy<b 判断是否在矩阵内【防止越界】
		   * 2.Math.abs(road[x][y]-road[dx][dy])==1||road[x][y]==road[dx][dy]
		   * 判断相邻的的两格数据是否一样或相差为1
		   * */
		  if(dx>=0 && dx<a && dy>=0 && dy<b && flag[dx][dy]==0 && (Math.abs(road[x][y]-road[dx][dy])==1||road[x][y]==road[dx][dy]))
		  {
    
    
			  //假定该相邻点可以连通,标记为1
			 flag[dx][dy] = 1;
			 //继续移动
			 dfs(dx,dy,num+1);
			 //走不通,标记为0
			 flag[dx][dy]=0;
		  }
			  
	  }
	  if(num>maxLen) {
    
    
		  maxLen=num;
	  }
	  
  }
}

猜你喜欢

转载自blog.csdn.net/weixin_45867159/article/details/109258488