zoukankan      html  css  js  c++  java
  • 之前写给同学的代码,关于搜索的一些题型

      其中有用到一些我自己写的类(栈,队列)改成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 }
  • 相关阅读:
    20145224&20145238 《信息安全系统设计基础》第二次实验
    《信息安全系统设计基础》 第九周学习总结
    20145224&20145238 《信息安全系统设计基础》 第一次实验
    《信息安全系统设计基础》 第八周学习总结
    《信息安全系统设计基础》 第七周学习总结
    《信息安全系统设计基础》 第六周学习总结
    在Ubuntu中创建与Windows的共享文件夹
    《信息安全系统设计基础》 第五周学习总结
    《信息安全系统设计基础》 第三周学习总结
    20145211 《信息安全系统设计基础》第十周学习总结——水流无限似侬愁
  • 原文地址:https://www.cnblogs.com/AardWolf/p/10056453.html
Copyright © 2011-2022 走看看