CSP201312-5(I'm struck!)(Java 100分)

问题描述
  给定一个R行C列的地图,地图的每一个方格可能是’#’, ‘+’, ‘-’, ‘|’, ‘.’, ‘S’, ‘T’七个字符中的一个,分别表示如下意思:
  ‘#’: 任何时候玩家都不能移动到此方格;
  ‘+’: 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非’#‘方格移动一格;
  ‘-’: 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非’#‘方格移动一格;
  ‘|’: 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非’#‘方格移动一格;
  ‘.’: 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为’#’,则玩家不能再移动;
  ‘S’: 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非’#‘方格移动一格;
  ‘T’: 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非’#‘方格移动一格。
  此外,玩家不能移动出地图。
  请找出满足下面两个性质的方格个数:
  1. 玩家可以从初始位置移动到此方格;
  2. 玩家不可以从此方格移动到目标位置。
输入格式
  输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。
  接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个’S’和一个’T’。
输出格式
  如果玩家在初始位置就已经不能到达终点了,就输出“I’m stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
样例输入
5 5
–±+
…|#.
…|##
S-±T
####.
样例输出
2
样例说明
  如果把满足性质的方格在地图上用’X’标记出来的话,地图如下所示:
  --±+
  …|#X
  …|##
  S-±T
  ####X

Java代码注释没怎么写,主要是大家应该好好研究一下广度优先搜索的算法。如果理解广搜,这个应该是比较容易理解的


import java.util.*;
public class IAmStuck {
	static int a[][]= {{1,0},{-1,0},{0,1},{0,-1}};
	static int n;
	static int m;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		n=sc.nextInt();
		m=sc.nextInt();
		char c[][]=new char[n][m];
		boolean vis[][]=new boolean[n][m];
		Node start = null;
		Node end = null;
		sc.nextLine();
		for(int i=0;i<n;i++) {//输入数据
			String s=sc.nextLine();
			for(int j=0;j<s.length();j++) {
				c[i][j]=s.charAt(j);
				if(c[i][j]=='S') {
					start=new Node(i, j);
				}
				if(c[i][j]=='T') {
					end=new Node(i, j);
				}
			}
		}
		Queue<Node> q = new LinkedList<Node>();
		q.add(start);
		vis[start.x][start.y]=true;
		while(!q.isEmpty()) {//遍历所有从起始点开始可以访问到的点。(广度优先搜索)
			Node node=q.poll();
			if(c[node.x][node.y]=='+') {
				for(int i=0;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='-') {
				for(int i=2;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='|') {
				for(int i=0;i<2;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='.') {
				for(int i=0;i<1;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='T') {
				for(int i=0;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='S') {
				for(int i=0;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&vis[t1][t2]==false) {
						vis[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else {
			}
			
			
		}
		if(vis[end.x][end.y]==false) {//如果无法访问到终点,则说明玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)
			System.out.println("I'm stuck!");
			return ;
		}
		int result=0;
		for(int i=0;i<n;i++) {
			for(int j=0;j<m;j++) {//对所有从起始点开始,都能访问到的点,判断其是否可以访问到重点
				if(vis[i][j]==true&&c[i][j]!='T'&&c[i][j]!='S'&&c[i][j]!='#') {//如果不可以,则另结果+1
					if(bfs(new Node(i,j),new boolean[n][m],c)==false) {
						result++;
					}	
				}	
			}
		}
		System.out.println(result);
	}
	static boolean bfs(Node start,boolean b[][],char c[][]){
		Queue<Node> q=new LinkedList<Node>();
		q.add(start);
		while(!q.isEmpty()) {
			Node node = q.poll();
			if(c[node.x][node.y]=='+') {
				for(int i=0;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&b[t1][t2]==false) {
						b[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='-') {
				for(int i=2;i<4;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&b[t1][t2]==false) {
						b[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='|') {
				for(int i=0;i<2;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&b[t1][t2]==false) {
						b[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='.') {
				for(int i=0;i<1;i++) {
					int t1=node.x+a[i][0];
					int t2=node.y+a[i][1];
					if(t1>=0&&t1<n&&t2>=0&&t2<m&&c[t1][t2]!='#'&&b[t1][t2]==false) {
						b[t1][t2]=true;
						q.add(new Node(t1,t2));
					}
				}
			}
			else if(c[node.x][node.y]=='T') {//如果访问到终点,则返回true
				return true;
			}
			else if(c[node.x][node.y]=='S') {//如果访问到起始点,那么一定会访问到终点
				//因为如果从起始点开始没有访问到终点,那么程序已经在第101行结束了,而不会运行到此处
				return true;
			}
			else {				
			}	
		}
		//如果程序访问了所有可以访问的点而没有访问到终点,则说明无法访问到终点
		return false;
	}
}
class Node{
	public int x;
	public int y;
	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

程序写的有点乱,希望大佬指出错误。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值