笔试题 迷宫求解
import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
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; } }