其中有用到一些我自己写的类(栈,队列)改成JDK自带的即可。。。
迷宫最短路径长度、最短路径、最大区域面积
1 import java.util.Scanner;
2
3 class BestMaze{ //这是我总结作业中,关于最佳图的问题,的类
4 int[] d1;
5 int[] d2;
6 int[][] map;
7 int m, n, count, minlen;
8 int l = 0; //l是指墙数(当然是有墙的情况才用)
9 Queue<Point> q;
10 Stack<Point> s;
11 Point[] wall;
12 public BestMaze(){
13 this(0,0,null,null);
14 }
15 public BestMaze(int m, int n, int[] d1, int[] d2){
16 this.m = m;
17 this.n = n;
18 this.d1 = d1; //搜索中纵坐标(也就是x)的偏移值数组
19 this.d2 = d2; //搜索中横坐标(也就是y)的偏移值数组
20 this.count = -1;
21 map = new int[m+1][n+1];
22 wall = new Point[(m+1)*(n+1)]; //纯英文意思就是,墙(就是这个位置走不了的意思)
23 }
24 public boolean meetWall(Point p){ //判断是否撞墙
25 if(!(p.x>=0 && p.x<m && p.y>=0 && p.y<n))
26 return false;
27 for(int j = 0; j < l; j++)
28 if(wall[j].x == p.x && wall[j].y == p.y)
29 return false;
30 return true;
31 }
32 public void Bestlen(Point start, Point end){ //队列广搜,蒽
33 map = new int[m+1][n+1];
34 q = new LinkedQueue<Point>();
35 map[start.x][start.y] = 1; //先把起始点标记了,不要跑路的时候又踩了这里
36 start.step = 0;
37 q.add(start);
38
39 while(!q.isEmpty()){
40 Point front = q.poll(); //队头搞出来
41
42 if(front.x == end.x && front.y == end.y){ //判断是否到达终点,到就停
43 minlen = front.step;
44 break;
45 }
46
47 for(int i = 0; i < d1.length; i++){
48 //移动的下一个点,定义为前一个点的偏移值后的位置
49 Point move = new Point(front.x+d1[i], front.y+d2[i], front.step+1);
50
51 boolean flag = meetWall(move); //判断墙,也可以结合某点是否走过使用
52
53 if(flag && map[move.x][move.y]==0){
54 q.add(move);
55 map[move.x][move.y] = move.step; //记录能到这个点的最快步数
56 }
57 }
58 }
59 map[start.x][start.y] = 0; //起始点当然还是要变回0的嘛
60 }
61 public void BestCount(Point start, Point end){ //其实是深搜,蒽
62 //最快到达的次数有多少种的方法,类似上面的地方就不备注了
63 map = new int[m+1][n+1];
64 s = new LinkedStack<Point>(); //注意这里用栈!
65 s.push(start);
66 start.step = 0;
67
68 while(!s.isEmpty()){
69 Point front = s.pop();
70
71 if(front.x == end.x && front.y == end.y)
72 count++;
73
74 for(int i = 0; i < d1.length; i++){
75 Point move = new Point(front.x+d1[i], front.y+d2[i], front.step+1);
76
77 boolean flag = meetWall(move);
78
79 if(flag && (map[move.x][move.y]==map[front.x][front.y]+1))
80 s.push(move);
81 //这里是不需要标记步数的,只要能走就入栈
82 }
83 }
84 }
85 public int BestArea(){ //这个也是深搜,想看效果可以把测试输出的地方取消备注,调用就可以了
86 int max = 0, t;
87 s = new LinkedStack<Point>();
88
89 for(int i = 0; i < m; i++)
90 for(int j = 0; j < n; j++){
91 if(map[i][j] == 1){ //这里是"1"是未走的路
92 t = 1;
93 s.push(new Point(i, j));
94 map[i][j] = 0; //"0"是墙
95
96 while(!s.isEmpty()){
97 Point f = s.pop();
98 for(int k = 0; k < d1.length; k++){
99 int dx = f.x + d1[k];
100 int dy = f.y + d2[k];
101
102 if(dx>=0 && dx<m && dy>=0 && dy<n && map[dx][dy] == 1){
103 s.push(new Point(dx, dy));
104 map[dx][dy] = 0; //走过就变成墙,也可以染色(某一块区域同一个数字)
105 t++;
106 }
107 }
108 }
109 // outMap(); //这是测试输出的地方
110 // System.out.println(t);
111 if(max < t) //这是找面积最大的
112 max = t;
113 }
114 }
115
116 return max;
117 }
118 //求最短路径,返回点集
119 public Point[] Bestload(Point start, Point end){
120 // Bestlen(start, new Point(-1, -1)); //广搜全图
121 Bestlen(start, end); //广搜终点
122 // outMap(); 广搜后再深搜
123
124 s = new LinkedStack<Point>();
125 s.push(start);
126 while(!s.isEmpty()){
127 Point front = s.peek();
128 boolean t = true;
129
130 if(front.x == end.x && front.y == end.y){
131 break;
132 }
133 for(int i = 0; i < d1.length; i++){
134 Point move = new Point(front.x+d1[i], front.y+d2[i]);
135
136 boolean flag = meetWall(move); //判断是否撞墙
137
138 if(flag && (map[move.x][move.y]==map[front.x][front.y]+1)){
139 wall[l++] = move; //走过的地方设置为墙
140 s.push(move);
141 // System.out.println("入栈:"+move + ",,"+map[move.x][move.y]);
142 t = false;
143 break; //确定一次走路只走一点
144 }
145 }
146 if(t){ //若此点四周都是墙,就丢了
147 // System.out.println("出--" + s.peek());
148 s.pop();
149 }
150 }
151 int len = map[end.x][end.y]+1; //结果集的长度肯定是深搜后到达终点的最小步数
152 Point[] result = new Point[len];
153
154 // StringBuffer sb = new StringBuffer(); //调试,查看结果
155 while(!s.isEmpty())
156 {
157 result[--len] = s.peek(); //倒序装回点集
158 // sb.insert(0, s.peek()); //调试,查看结果
159 s.pop();
160 }
161
162 // System.out.println(sb.toString()); //调试,查看结果
163 return result;
164 }
165 public void outMap(){ //查看图的情况
166 for(int i = 0; i < m; i++){
167 for(int j = 0; j < n; j++)
168 System.out.print(map[i][j] + " ");
169 System.out.println();
170 }
171 }
172
173 public static void migonglujing(String[] args) { //最短迷宫路径的main方法
174 Scanner sc = new Scanner(System.in);
175 int id = 1;
176 int[] d1 = {0, 1, 1, 1, 0, -1, -1, -1};
177 int[] d2 = {1, 1, 0, -1, -1, -1, 0, 1};
178 while(sc.hasNext()){
179 int m = sc.nextInt();
180 int n = sc.nextInt();
181 // if(m == 0 && n == 0) break;
182 BestMaze maze = new BestMaze(m, n, d1, d2);
183 int l = 0;
184 for(int i = 0; i < m; i++)
185 for(int j = 0; j < n; j++)
186 if(sc.nextInt() == 1) //输入为1,是墙
187 maze.wall[l++] = new Point(i, j);
188 maze.l = l; //确定墙的数量
189 Point[] result = maze.Bestload(new Point(0, 0), new Point(m-1, n-1));
190 for(int i = 0; i < result.length-1; i++)
191 System.out.print(result[i] + "->");
192 System.out.print(result[result.length-1]);
193
194 }
195 System.gc();sc.close();
196 }
197
198 public static void Qishijuhui(String[] args) { //这是骑士聚会问题的main方法
199 Scanner sc = new Scanner(System.in);
200 int id = 1;
201 int[] d1 = {-2, -1, 1, 2, 2, 1, -1, -2};
202 int[] d2 = {1, 2, 2, 1, -1, -2, -2, -1};
203 while(sc.hasNext()){
204 int n = sc.nextInt();
205 int m = sc.nextInt();
206 // if(m == 0 && n == 0) break;
207 BestMaze[] maze = new BestMaze[m]; //求出每个骑
208 for(int i = 0; i < m; i++){
209 maze[i] = new BestMaze(n, n, d1, d2);
210 maze[i].Bestlen(new Point(sc.nextInt(), sc.nextInt()), new Point(-1, -1));
211 }
212 // // 查看广搜后的结果,你可以取消备注看看。。。
213 // int[][] count = new int[n][n];
214 //
215 // for(int i = 0; i < m; i++){
216 // for(int j = 0; j < n; j++){
217 // for(int k = 0; k < n; k++){
218 // count[j][k] += maze[i].map[j][k];
219 // System.out.print(maze[i].map[j][k] + " ");
220 // }
221 // System.out.println();
222 // }
223 // if(i == m-1){
224 // System.out.println("------------总步数--------------");
225 // for(int j = 0; j < n; j++){
226 // for(int k = 0; k < n; k++)
227 // System.out.print(count[j][k] + " ");
228 // System.out.println();
229 // }
230 // }
231 // System.out.println("-------------------------------");
232 // }
233 // // 下面开始找最佳位置(所有骑士到这里的总天数最小,天数相等情况下要最晚到的骑士步数最小的)
234
235 int[][] countday = new int[n][n];
236 int minday = 99999;
237 int lastday = 0;
238 Point bestposition = null;
239
240 for (int i = 0; i < n; i++)
241 for (int j = 0; j < n; j++) {
242 int day = 0;
243 int last = 0; //这个位置上,最晚到达的骑士的天数
244
245 for (int k = 0; k < m; k++) { //求所有骑士到这位置的总天数
246 day += maze[k].map[i][j];
247 if (maze[k].map[i][j] > last) //记住最晚的那个
248 last = maze[k].map[i][j];
249 }
250 if (minday > day) { //要天数最小的位置
251 minday = day;
252 bestposition = new Point(i, j);
253 lastday = last;
254 }
255 //天数相等情况下,要最晚到达的骑士的步数最小的位置
256 else if (minday == day && last < lastday) {
257 bestposition = new Point(i, j);
258 lastday = last;
259 }
260 countday[i][j] = day;
261 }
262 System.out.println("最佳聚会位置: " + bestposition);
263 System.out.println("最晚到达聚会的骑士走了" + lastday +"天");
264 System.out.println("总步数为: " + countday[bestposition.x][bestposition.y]);
265 }
266
267 System.gc();sc.close();
268 }
269 }
一个黑白区域面积的题目,类似染色问题
1 import java.awt.*;
2 import java.util.*;
3
4 public class Main{
5 static Scanner sc = new Scanner(System.in);
6
7 static int[] d1 = {0, 0, 1, -1};
8 static int[] d2 = {1, -1, 0, 0};
9 static int dfs(int[][] map, int m, int n, int i, int j, int num){
10 int t = 1;
11 Stack<Point> stack = new Stack<Point>();
12 map[i][j] = 0;
13 stack.push(new Point(i, j));
14 while(!stack.isEmpty()){
15 Point p = stack.pop();
16 for(int k = 0; k < 4; k++){
17 int dx = p.x + d1[k];
18 int dy = p.y + d2[k];
19 if(dx>0 && dx<m && dy>=0 && dy<n && map[dx][dy] == num){
20 map[dx][dy] = 0; t++;
21 stack.push(new Point(dx, dy));
22 }
23 }
24 }
25 return t;
26 }
27
28 public static void main(String[] args) {
29 while(sc.hasNext()){
30 int m = sc.nextInt();
31 int n = sc.nextInt();
32 int[][] map = new int[m][n];
33
34 for(int i = 0; i < m; i++){
35 String s = sc.next();
36 for(int j = 0; j < n; j++){
37 if(s.charAt(j) == 'D')
38 map[i][j] = -1;
39 if(s.charAt(j) == 'W')
40 map[i][j] = 1;
41 }
42 }
43
44 int maxD = 0, maxW = 0, t;
45 for(int i = 0; i < m; i++){
46 for(int j = 0; j < n; j++){
47 if(map[i][j] == 1){
48 t = dfs(map, m, n, i, j, 1);
49 maxW = maxW>t? maxW:t;
50 }
51 if(map[i][j] == -1){
52 t = dfs(map, m, n, i, j, -1);
53 maxD = maxD>t? maxD:t;
54 }
55 }
56 }
57 System.out.println(maxW + " " + maxD);
58 }
59 System.gc();sc.close();
60 }
61
62 }