单元测验,一开始完全没思路,老师给了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;
}
}
}