之前写给同学的代码,关于搜索的一些题型

  其中有用到一些自己写的类(栈,队列)改成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] + "\t");
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] + "\t");
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 }

原文地址:https://www.cnblogs.com/AardWolf/p/10056453.html

时间: 2024-08-30 13:48:53

之前写给同学的代码,关于搜索的一些题型的相关文章

[转帖]知道这20个正则表达式,能让你少写1,000行代码

知道这20个正则表达式,能让你少写1,000行代码 https://zhuanlan.zhihu.com/p/29163295 一直说要学习 正则 一直没学习.. 正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑.熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升. 正则表达式经常被用于字段或任意字符串的校验,如下面这段校验基本日期格式的JavaScript代码: var reg = /^(\\d{1,4})(-|\\/

写一手简洁的代码

如果有人问我,为什么开始写代码...我会毫不犹豫的告诉他,因为IDEA的代码五颜六色的,很漂亮!!是的,我热爱写代码的初衷就是因为代码好"漂亮".从第一次开始写代码,到现在已经快2年了,"漂亮"这个词一直是我对代码热爱的初衷,只不过曾经的"漂亮"只局限于代码的颜色与字体,而现在的"漂亮"已经涵盖了颜色,接口,注释,方法,类等等,总之我喜欢写代码,只是因为它"漂亮". 之前在学校的时候,我就被实验室的同学&q

如何写出无法维护的代码

如何写出无法维护的代码 酷壳里有很多我觉得很不错的文章,但是访问量最大的却是那篇<6个变态的Hello World>,和它能在本站右边栏“全站热门”中出现的还有“如何加密源代码”,以及编程真难啊等这样的文章.可见本站的读者们的偏好,我也相信你们都是“身怀绝技”的程序员.所以,今天给大家推荐这篇文章,相信一定能触动大家的兴奋点. 这篇文章的原文在这里(http://mindprod.com/jgloss/unmain.html),我看完后我想说—— 什么叫“创造力”,创造力就是——就算是要干一件

怎样写出无法维护的代码

每次写代码的时候,我都尽量写出一个尽可能方便其他人看得懂的代码,没办法,很多时候维护也是我自己,活着小的看不懂,还是我自己出手.但今天我想反其道而行之,怎样才能写出一份无法维护的代码. 原文在这里,原文翻译了一点,再加上自己的理解. 这个无法维护的代码是什么? 如果你的代码根本是别人看不懂,那不好意思,如果是我,我会尽可能另外写一份,或者一边看代码,一边注释,还有重命名,总之最后还是让我改了一遍就完事了.如果仅仅是这样,我觉得,还不是无法维护吧.应该看起来还算正常,而且有详细的注释,让人充满希望

力荐!这些工具可以帮你写出干净的代码

作者|Adeel Imran译者|无明 想写出好代码,却不知道从哪里开始?想删除死代码?想在代码库中找出未被使用的变量?想在代码中找出有问题的模式? 你是多元化团队的负责人吗?你的团队中有新来的开发人员吗?你担心他们会写出不符合标准的代码吗?在代码评审时是否花了一整天的时间去检查代码标准,而不是实际的逻辑实现? 我一直在做这样的事情,经常忙得像热锅上的蚂蚁.但从现在开始,我们要保证永远不再担心这类问题.在阅读本文过程中,如果遇到困难,可以参考代码库(https://github.com/adee

javascript写的新闻滚动代码

在企业站中,我们会看到很多新闻列表很平滑的滚动,但是这种功能自己写太浪费时间,下面是我整理好的一组很常用的新闻列表滚动,有上下分页哦! 1.body里面 1 <div class="tz_tagcgnewcontent"> 2 <div id="feature-slide-block"> 3 <div class="tz_newlist"> 4 <div class="tz_newimg&quo

写可测试的代码

任何一个软件都是可以测试.在某种意义上,用户的使用过程也就是一个软件测试的过程.可是这并不是我们今天要讲的可测试性.我们讲的可测试性指的是代码的可测试性,通俗点儿说就是是一串代码里包含的逻辑是不是可以被单元测试所覆盖.在这篇文章里我会从单元测试的基本概念开始引伸到如何写单元测试,如何写可单元测试的代码.文章里所有的例子都是C#写的,一来它是我职业生涯的主力语言.二来C#广为人知,相信对广大职业的或是业余的程序员来说读懂C#的代码不会是什么特别困难的事情.实际上我描述的方法和概念并不会局限于C#或

开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码

开源一个Mac漂亮的小工具 PPRows for Mac, 在Mac上优雅的计算你写了多少行代码. 开源地址: https://github.com/jkpang/PPRows

山大泰克条屏写串口的核心代码(海宏原创,转载请注明)

山大泰克条屏写串口的核心代码,海宏原创,转载请注明. using System; using System.Collections.Generic; using System.Text; // using System.Runtime.InteropServices; using System.IO.Ports; using System.Windows.Forms; using iPublic; namespace sdLed { /// <summary> /// 用来连接LED的API.