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;
}
}