【期末算法课程设计十道题】-【DFS】-【3-迷宫求解所有路径 】(为什么JAVA不行C++行???)

大家好,我是被白菜拱的猪。

一个热爱学习废寝忘食头悬梁锥刺股,痴迷于girl的潇洒从容淡然coding handsome boy!

没想到这一题竟然搞了两天,我真的受不了了!为什么java通不过,c++居然能通过,同样的思路。
在这里插入图片描述
在这里插入图片描述
我跟同学探讨了一下,他用c++写的,我用java写的。
不管怎么说菜是原罪啊。
日后好好学习算法
第三题
7-3 Link-Cut-tree(DFS and similar)
Description
Lct prepares to study an Algorithm named ‘Link−Cut−Tree’,he think the algorithm is vary beautiful,so everyday he says , ‘lcttxdy’.One day,he picked a n∗m chessboard,but that makes him very strange is every checker in the chessboard has a small letter,he wants to know how many case letters which is linked together can constitute ‘lcttxdy’.

Note:only when one letter is up, down, left, right, upper left, bottom left, upper right and bottom right,we call the two letters is linked together.

Input
The first line contains an integer t(1≤t≤100) ----- the number of test cases in the input.

The first line of each test case contains two integer n and m ---- the length and width of checkerboard (1≤n,m≤100)

The next n line each line contains m letter,all of them are lowercase English letters

Output
For each case, output two lines:

In the first line output the “YES” or “NO” — find or not find “lcttxdy”

In the second line output the number of “lcttxdy”. if not find print -1

Example
input
4
1 4
dfsz
1 7
lcttxdy
2 6
lctxdy
ydxtdy
2 7
lcttxdy
lcttxdy
output
NO
-1
YES
1
YES
5
YES
128
Tag
DFS and similar


首先讲讲我做题的思路,题目提示是DFS,我去网上搜了搜什么是DFS(深度优先遍历),然后查了查相关题目,发现迷宫求解所有路径并打印与之类似,我在想,既然把所有路径都打印出来了,然后与正确的路径比对一下不就ok了嘛,迷宫求解只有一个起点,一个终点,这里抽象一下,无非是多个起点多个终点,分别讨论一下不就ok了。所有有了第一种解题思路。
附上我思路的链接
但是最后PTA没有AC过去,第一个就答案错误,我在想是不是这个太复杂了,正好我同学第三题没有思路,我把我的想法讲给他听,然后又完善了一下,因为把所有的路径打印出来太耗时间,假如一开始就有判断,比如没有按照正确的路径走,就算错,步数大于也算错。这是改善过后的,因为第二种思路在第一种的改善的,所以没有保存。
no 代码 you say 个 jb!

JAVA1

/**
 * 
 */
package com.java.algorithm;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;

/**  
* @ClassName: Demo3  
* @Description: TODO(这里用一句话描述这个类的作用)  
* @author Lily  
* @date 2020年6月18日    
*/
public class Demo3 {
	
	//起点数组
	public static List<Point> start=new ArrayList<Point>();
	//终点数组
	public static List<Point> end=new ArrayList<Point>();
	//是否访问 1-已访问,2-未访问
	public static int[][] visit;
	//lcttxdy出现的次数
	public static int count=0;
	//栈用来记录路径
	//八个方向,上下左右,以及对角
	public static int[][] direction={{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; 
	
	public static Stack<Point> path=new Stack<>();
	public static Stack<Point> temp=new Stack<>();
	
	/**
	 * 定义一个点类
	 */
	class Point{
		//坐标
		int x;
		int y;
		Point(int x,int y){
			this.x = x;
			this.y = y;
		}
	}
	public static String str="";
	//深度优先遍历,x,y代表当前坐标,point代表终点坐标,map 表示地图
	public static void dfs(int x,int y,Point point,int step,char[][] map){
		str+=map[x][y];
		//遍历到终点,打印出路径,判断是否与"lcttxdy",相等,count++
		if(x==point.x &&y==point.y && step==7){
			/*//将path里面的点取出来,放在temp里面
			while(!path.isEmpty()){
				Point p=path.pop();
				temp.push(p);
			}
			while(!temp.empty())
			{//输出temp里面的路径,这样刚好是从起点到终点的顺序
				Point p2 = temp.pop();
				path.push(p2);//将路径放回path里面,因为后面还要回溯!!!
				str+=map[p2.x][p2.y];
			}
			if(str.equals("lcttxdy")){
				count++;
			}*/
			count++;
			//System.out.println(str);
			//str="";
			return;
		}
		
		//判断是否越界
		if(x<0 || x>=map.length || y<0 || y>=map[0].length)//越界
			return;
		//根据步数,假如超过7步  lcttxdy七步
		if(step>7 ){
			return; 
		}else{
			if(step==2&&!((map[x][y]+"").equals("c"))){
				return;
			}
			if(step==3&&!((map[x][y]+"").equals("t"))){
				return;
			}
			if(step==4&&!((map[x][y]+"").equals("t"))){
				return;
			}
			if(step==5&&!((map[x][y]+"").equals("x"))){
				return;
			}
			if(step==6&&!((map[x][y]+"").equals("d"))){
				return;
			}
		}
		
		//没有越界,然后从八个方向探测
		for(int i=0;i<8;i++){
			int nx=x+direction[i][0];
			int ny=y+direction[i][1];
			
			//条件:nx,ny没有出界,visit[nx][ny]==0说明(nx,ny)没有访问过,可以访问
			if(0<=nx && nx<map.length && 0<=ny && ny<map[0].length &&  visit[nx][ny]==0)
			{
				visit[nx][ny]=1;//设为访问过
				//Point p3=new Main().new Point(nx,ny);
				//path.push(p3);//让当前点进栈
				dfs(nx,ny,point,step+1,map);//进一步探测
			
				visit[nx][ny]=0;//回溯
				//path.pop();//由于是回溯,所以当前点属于退回去的点,需要出栈
			}

		}

	}
	
	
	
	public static void main(String[] args) {
		//用来存放地图
		List<char[][]> list=new ArrayList<>();
		//输入
		Scanner scan=new Scanner(System.in);
		int times=scan.nextInt();
		for(int i=0;i<times;i++){
			//长,宽
			int n=scan.nextInt();
			int m=scan.nextInt();
			char[][] map=new char[n][m];
			list.add(map);
			
			//输入地图
			for(int j=0;j<map.length;j++){
					map[j]=scan.next().toCharArray();
			}
		}
		//对每个地图进行操作
		for(int i=0;i<list.size();i++){
			count=0;
			start.clear();
			end.clear();
			char[][] map=list.get(i);
			//start.clear();
			//end.clear();
			//找出起点与终点
			for(int p=0;p<map.length;p++){
				for(int q=0;q<map[0].length;q++){
					//添加起点
					if((""+map[p][q]).equals("l")){
						start.add(new Demo3().new Point(p, q));
					}
					//添加终点
					if((""+map[p][q]).equals("y")){
						end.add(new Demo3().new Point(p, q));
					}
				}
			}
			
			
			for(Point startp:start){
				for(Point endp:end){
					visit=new int[map.length][map[0].length];
					//初始化,0未到达
					for(int l=0;l<visit.length;l++){
						for(int k=0;k<visit[0].length;k++){
							visit[l][k]=0;
						}
					}
					
					//将起点设为已访问
					visit[startp.x][startp.y]=1;
					//将起点插入
					//path.push(startp);
					dfs(startp.x,startp.y,endp,1,map);
					//path.clear();
					//temp.clear();
				}
			}
			if(count!=0){
				System.out.println("YES");
				System.out.print(count);
			}else{
				System.out.println("NO");
				System.out.print("-1");
			}
			if(i!=list.size()-1){
				System.out.println();
			}
		}
		
		
		
	}
	
	
	
}

我的没有通过,我放弃了,周一还有考试,一丁点没有复习呢,很不甘心很不甘心很不甘心!没有办法,下午的时候同学说照我的思路过了,我看了看他的确实,思路跟我一样,但是比我的代码简洁多了,希望仿佛就在眼前,我于是把他的c++版本改成java,又提交了一遍,还是出错!气死我了!!!

JAVA2

/**
 * 
 */
package com.java.algorithm;

import java.util.Scanner;

/**  
* @ClassName: Demo3_1  
* @Description: TODO(这里用一句话描述这个类的作用)  
* @author Lily  
* @date 2020年6月19日    
*/
public class Demo3_1 {
	//定义一个数组,存放count值
	public static int value[];
	
	//用来记录数量
	public static int count=0;
	
	//地图的行列
	public static int rows=0,colunm=0;
	
	//地图
	public static char[][] map=new char[100][100];
	
	//正确的路径
	public static char road[] = { 'l','c', 't', 't','x','d','y' };
	
	//方向
	public static int[][] dir = { {1,0},{0,1},{-1,0},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1} };

	// k匹配字符串中第k+1个字符
	public static boolean check(int x, int y, int k) {
		if (x < 0 || y < 0 || x >= rows || y >= colunm) {
			return false;
		}
		return map[x][y] == road[k];
	}
	
	public static void dfs(int x, int y, int k) {
		// 剪枝:长度超过7
		if (k >= 7) {
			return;
		}
		// 到达终点
		if (k == 6) {
			count++;
			return;
		}
		for (int i = 0; i < 8; i++) {
			int nx = x + dir[i][0];
			int ny = y + dir[i][1];
			if (check(nx, ny, k + 1)) {
				dfs(nx, ny, k + 1);
			}
		}
		return;
	}
	
	public static void main(String[] args) {
		

		
		Scanner scan=new Scanner(System.in);
		int times=scan.nextInt();
		value=new int[times];
		for(int i=0;i<times;i++){
			//每一次运行,count清零
			count=0;
			//输入行和列
			rows=scan.nextInt();
			colunm=scan.nextInt();
			for(int m=0;m<rows;m++){
				map[m]=scan.next().toCharArray();
			}
			for(int m=0;m<rows;m++){
				for(int n=0;n<colunm;n++){
					if (map[m][n] == 'l') {
						dfs(m, n, 0);
					}
				}
			}
			value[i]=count;
		}
		for(int i=0;i<times;i++){
			if(value[i]<=0){
				System.out.println("NO");
				System.out.print("-1");
			}else{
				System.out.println("YES");
				System.out.print(value[i]);
			}
			if(i!=times-1){
				System.out.println();
			}
		}
	}
}

唉,无奈白给了现实,我太菜了,最后把同学的c++版改了改变量什么的,提交了上去,希望不要查重被发现。发现就发现吧,我问心无愧。

C++

#include <iostream>
#include<string.h>
using namespace std;
//行,列
int rows = 0, column = 0;
//地图
char map[100][100];
//八个方向
int direction[8][2] = { {-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1} };

//正确的路径
char road[] = { 'l','c', 't', 't','x','d','y' };
//用来记录正确到达的次数
int num;



//判断是否符合正确路径
bool is(int x, int y, int k) {
	if (x < 0 || y < 0 || x >= rows || y >= column) {
		return false;
	}
	return map[x][y] == road[k];
}

void dfs(int x, int y, int k) {
	// 剪枝:长度超过7
	if (k >= 7) {
		return;
	}
	// 到达终点
	if (k == 6) {
		num++;

	}
	for (int i = 0; i < 8; i++) {
		int nx = x + direction[i][0];
		int ny = y + direction[i][1];
		if (is(nx, ny, k + 1)) {
			dfs(nx, ny, k + 1);
		}
	}
	return;
}

int main() {
	int times;
	cin >> times;
	for (int i = 0; i < times; i++) {
		num = 0;
		cin >> rows >> column;
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < column; j++) {
				cin >> map[i][j];
			}
		}
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < column; j++) {
				if (map[i][j] == 'l') {
					dfs(i, j, 0);
				}
			}
		}
		if (num > 0) {
			cout << "YES" << endl;
			cout << num;
		}
		else {
			cout << "NO" << endl << "-1";
		}
	
		if (times) cout << endl;
	}
	return 0;
}

唉,加油!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值