搜索一般由以下几种

  • 状态空间
  • 状态转移
  • 起始状态
  • 目标状态

查看复核索引 搜索复复_递归


上图就是个例子,下面是一个稍微修改要求的图

查看复核索引 搜索复复_System_02


状态空间图一般比较大,很难在计算机中用这些。

可以转换为树来求解。

查看复核索引 搜索复复_System_03

  • 宽度优先搜索(BFS)
  • 深度优先搜索(DFS)

emm,就不做说明了。

例题9.1

查看复核索引 搜索复复_System_04


简单来说,就是一个数组(0,100000)农夫在下标n的位置,牛在下标k的位置。农夫每次要么n+1,要么n-1,要么n*2.

假设牛没有意识到农夫在追它,在原地不动,农夫最少要多久找到。

查看复核索引 搜索复复_数组_05


查看复核索引 搜索复复_查看复核索引_06


这里需要注意的是

查看复核索引 搜索复复_数组_07


这两个点重复了,它们仅仅是时间不同。所以说我们不必重复查找。提高效率。

这里额外补充以下,这里n的数据量是105很明显半提示那种要用logn的时间。

这里明显可以用递归,但是递归是深度优先的。并不是宽度优先。

static void BFS(int n , int k,boolean visit[]){
        Queue<Status> queue = new LinkedList<Status>();
        queue.offer(new Status(n,0));
        visit[n] = true;
         while (!queue.isEmpty()){
             Status current = queue.poll();
             if(current.position==k){
                 System.out.println(current.time);
             }
             for (int i = 0; i < 3; i++) {
                 Status next = new Status(current.position, current.time);
                 if(i==0){
                     next.position-=1;
                 }else if(i==1){
                     next.position+=1;
                 }else {
                     next.position*=2;
                 }
                 next.time+=1;
                 if(next.position<0 ||next.position>100000||visit[next.position]){
                     continue;
                 }
                 queue.offer(next);
                 visit[next.position]=true;
             }
         }
    }

不是很难,利用队列的先进先出即可层次遍历。
还是要稍微注意一下队列的基本操作
Queue queue = new LinkedList();
add
remove
offer
poll
由于java语言的特性,每次最好new一个对象添加,出队得时候由于没有对象引用会自动被回收。这里要注意一点。

例题9.2

查看复核索引 搜索复复_数组_08


翻译过来就是,输入一个整数,输出一个能整除它的数,这个数很特别,它只包含0和1。在不超过100得数里面肯定有一个满足题目要求。

查看复核索引 搜索复复_System_09


查看复核索引 搜索复复_数组_10

static void BFS(int n){
        Queue<Long> queue = new LinkedList();
        queue.offer(1l);
        while (!queue.isEmpty()){
            Long current = queue.poll();
            if(current%n==0){
                System.out.println(current);
                return;
            }
            queue.offer(new Long(current*10));
            queue.offer(new Long(current*10+1));
            //满足只有01两种数得数。
        }
    }

很简单的啦。

例题9.3

查看复核索引 搜索复复_System_11


骑士走日字,只有八种移动方式。

查看复核索引 搜索复复_递归_12


这里可以用递归就好。实现深度,如果再加上字典序(从左到右)

查看复核索引 搜索复复_查看复核索引_13


则需要这种类型的东西,(上图c++实现);

其次设计一个visited数组,和路径数组(或字符串)。

之后递归就好了。这里不过多解释。记得参数有x,y,步数,路径。哦