笔试题 迷宫求解

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

1.使用回溯法    

 开始使用递归,基于回溯的算法,也算是深度遍历,可惜没有做出来。走过的每个点时,拿到的钥匙,不会到该怎么存。在回溯的过程中,每个点存储的钥匙状态怎么变化?这一点没有想通。无奈放弃!

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
	static class Node{
		int x=0;int y=0;int cnt=0;int status=0;
	}
    public static void  main(String[] args){
    	Scanner sc=new Scanner(System.in);
    	    char[][] arr={{'0','2','1','1','1'}
    	                 ,{'0','1','a','0','A'},
    	                  {'0','1','0','0','3'}
    	                 ,{'0','1','0','0','1'}
    	                 ,{'0','1','1','1','1'}};
    	    int[] myPos={0,1};
    	    int[] outPos={2,4};
    	    boolean[][][] vis=new boolean[arr.length][arr[0].length][10];
    	    boolean falg=recursion(arr,vis,myPos,outPos);
    	    System.out.println(step);
    	sc.close();
    }
    public static boolean isValid(char[][] arr,boolean[][][] vis,int[] pos){
    	int m=arr.length;
    	int n=arr[0].length;
    	int x=pos[0];
    	int y=pos[1];
    	if(x>=m)
    		return false;
    	if(x<0)
    		return false;
    	if(y>=n)
    		return false;
    	if(y<0)
    		return false;
    	//碰到墙了
    	if(arr[x][y]=='0'){
    		return false;
    	}
    	//碰到钥匙了
    	if(arr[x][y]>='a' && arr[x][y]<='z'){
    		char key=arr[x][y];
    		1>>(key-'a');
    	}
     	//碰到门了
    	if(arr[x][y]>='A' && arr[x][y]<='Z'){
    		char up=Character.toLowerCase(arr[x][y]);
    		if(!set.contains(up)){
    			return false;
    		}
    	}
    	return true;
    }
    static int step=0;
    public static boolean recursion(char[][] arr,boolean[][][] vis,int[] myPos,int[] outPos){
    	if(!isValid(arr,vis,myPos)){
    		return false;
    	}
    	if(Arrays.equals(myPos, outPos)){
    		return true;
    	}
    	step++;
    	int[] newPos={myPos[0]-1,myPos[1]};
    	boolean flag=recursion(arr,vis,newPos,outPos);
    	if(flag){
    		return flag;
    	}
    	step--;
    	step++;
    	int[] downPos={myPos[0]+1,myPos[1]};
    	flag=recursion(arr,downPos,outPos);
    	if(flag){
    		return flag;
    	}
    	step--;
    	step++;
    	int[] rightPos={myPos[0],myPos[1]+1};
    	flag=recursion(arr,rightPos,outPos);
    	if(flag){
    		return flag;
    	}
    	step--;
    	step++;
    	int[] leftPos={myPos[0],myPos[1]-1};
    	flag=recursion(arr,leftPos,outPos);
    	if(flag){
    		return flag;
    	}
    	step--;
    	return false;
    }
    
}


2.基于栈结构的宽度遍历

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
	static int[] fx={0,0,1,-1};
	static int[] fy={1,-1,0,0};
	static class Node{
		int x=0;int y=0;int status=0;int step=0;
	}
    public static void  main(String[] args){
    	Scanner sc=new Scanner(System.in);
    	    char[][] arr={{'0','2','1','1','1'}
    	                 ,{'0','1','a','0','A'},
    	                  {'0','1','0','0','3'}
    	                 ,{'0','1','0','0','1'}
    	                 ,{'0','1','1','1','1'}};
    	    int[] myPos={0,1};
    	    int[] outPos={2,4};
    	    //1024代表钥匙的1024中状态
    	    boolean[][][] vis=new boolean[arr.length][arr[0].length][1024];
    	    int pathLen=shortestWay(arr,vis,myPos,outPos);
    	    System.out.println(pathLen);
    	    sc.close();
    }
    public static int shortestWay(char[][] arr,boolean[][][] vis,int[] myPos,int[] outPos){
    	if(myPos[0]==outPos[0] && myPos[1]==outPos[1]){
    		return 0;
    	}
    	Queue<Node> que=new LinkedList<Node>();
    	Node node=new Node();
    	node.x=myPos[0];
    	node.y=myPos[1];
    	que.add(node);
    	while(!que.isEmpty()){
    		Node top=que.peek();
    		if(top.x==outPos[0] && top.y==outPos[1]){
    			return top.step;
    		}
    		que.poll();
    		for(int i=0;i<4;i++){
    			int newX=top.x+fx[i];
    			int newY=top.y+fy[i];
    			if(newX<0 || newX>=arr.length || newY<0 || newY>=arr[0].length ) continue;
    			if(arr[newX][newY]=='0') continue;
    			
    			int status=top.status;
    			//二进制第一位为1 代表有a钥匙  第二位代表有b钥匙
    			if(arr[newX][newY]>='a' && arr[newX][newY]<='z'){
    				status|=1<<(arr[newX][newY]-'a');
    			}
    			if(vis[newX][newY][status]) continue;
    			if(arr[newX][newY]>='A' && arr[newX][newY]<='Z'){
    				int f=status&1<<(arr[newX][newY]-'A');
    			    if(f==0){
    			    	continue;
    			    }
    			}
    			
    			Node tmp=new Node();
    			vis[newX][newY][status]=true;
    			tmp.x=newX;tmp.y=newY;tmp.status=status;tmp.step=top.step+1;
    			que.add(tmp);
    		}
    	}
    	return -1;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值