`
200830740306
  • 浏览: 109470 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

poj1915 广度优先遍历

阅读更多
问题重述:
背景
神话般的国际象棋玩家Somurolov先生,他声称,他可以把一个骑士从一个位置很快地移动到另一个位置,但其他人却不行。你能打败他吗?
存在的问题
你的任务是编写一个程序来计算的骑士达到从另一个位置所要移动的最少步数,这样你才有机会比Somurolov快。
也许人们不熟悉的国际象棋,骑士行动可能在如图1所示。

输入
首先在第一个行,输入n,表示有n种的情况。
接下来是n方案。每个方案包括三行。第一行指定一个棋盘边长L(4<=L<= 300)。整个棋盘的尺寸L *L.第二和第三行包含整数对(0,...,L - 1)*(0,...,L - 1)指定骑士开始和结束位置。整数对由一个空白分隔开。
输出
对于每个输入你要计算骑士的行动,有必要从起点移动到终点最少步数的情况。如果起点和终点都是平等的,距离是零。
2.解题过程:
分析过程:
当读懂了题意后,发现这可能是一道最短路径的应用,但当看到图算法的题目后,再仔细想下,这是一道广度优先遍历的应用,利用广搜去求最短路径比较简单。采用广度优先去搜索,一旦找到了就可以由搜索的深度去求出所需的最少步数。而广度优先的算法要用到队列,平时也做过练习,所以在算法上也就没有什么问题。而这道题的数据的输入问题,相对挺简单的。但存储就有点麻烦,因为棋盘的大小是从4*4到300*300,跨度比较大,如果只是定义最大的二维数组来存储,可能会浪费很多空间,此外,队列要存储的是一个棋盘的格子,所以要存至少两个数,为了方便,我直接使用两个整型的队列存储两个下标,感觉不难。
编程过程:
到了具体编程时,我才发现,如何由搜索的深度去求出所需的最少步数,这一步的实现挺麻烦的。我之前打算直接用以前写过的int型队列难以实现,除了要记录棋格的x,y坐标,还要记录棋格的步数。要不就只能重新定义一个新的结构体的队列,要不就得多个队列并行使用,但两者都挺麻烦的。所以我就想到如果我C++里有直接的队列可以使用,但我不会C++。最后发现poj上是可以提交java代码的,再想到下学期我得考sun的scjp认证,得复习下java。所以,最后打算用java来做。于是,我很快就用java把代码编出来了,自己测试也通过了,但提交时却说内存溢出。想了很久后,就大概猜到是什么原因,最初我是在得到size后就把整张棋盘都建了出来。这样就产生了很多的对象,自然多了许多没有用的对象霸占了许多内存。之后我就改为当需要时才去建棋格子的对象,果然少占了很多内存。但提交时,却发现运行错误,可是我自己测试却没问题,所以郁闷了很久。最后,发现有的地方会出现空指针异常,终于通过了。
3.做题收获:
通过这一道题,我找到了一个既可以练习java,又可以学到算法的途径,以后要多用java到poj上刷题才行。此外,我对java中的内存分配机制,有了更多的理解。题目虽然是通过了,但跟那些以前通过的人相比,我占用的内存还是太多了,这方面有待加强。用java做了题目后,我发现用C和java写代码,虽然用的算法是一样的,但对数据的输入与存储处理都有各自的优缺点。
程序源码
package middle;


import java.io.BufferedInputStream;
import java.util.LinkedList;
import java.util.Scanner;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 * poj1915最初做这道题时,我是就c去做的,但到了具体编程时,我发现有些地方要用到
 * 自定义类型的队列,自己去重写那些队列显行太麻烦了,本来C++就有现成的queue可以
 * 用,但我没学过c++,所以就想到用java。代码也很快就写了出来,但提交时却说内存溢出
 * 想了很久后,就大概猜到是什么原因,最初我是在得到size后就把整张棋盘都建了出来。
 * 这样就产生了很多的对象,自然多了许多没有用的对象霸占了许多内存。之后我就改为
 * 当需要时才去建棋格子的对象,果然少了很多内存。最后终于通过了。不过跟那些以前通过
 * 的人相比,我占用的内存还是太多了。
 * @author NC
 */
public class Poj1915 {

    private static int[][] directions = new int[][]{
        {-2, -1}, {-2, 1}, {-1, -2}, {-1, 2}, {1, -2}, {1, 2}, {2, -1}, {2, 1}};

    static void BreadthFirstSearch(int startX, int startY,
            chessNode[][] chessPanel, int size) {
        chessNode currentNode = null, nextNode = null;
        LinkedList<chessNode> queue = new LinkedList();
        currentNode = chessPanel[startY][startY] =
                new chessNode(startX, startY, true, 0, false);
        queue.addLast(currentNode);//初始棋格入队
        while (!queue.isEmpty()) {
            currentNode = queue.removeFirst();//出队
            if (currentNode.isTarget()) {//如果走到了目的位置
                break;
            }
            for (int i = 0; i < 8; i++) {
                //遍历八个方向
                int x = currentNode.getX() + directions[i][0];
                int y = currentNode.getY() + directions[i][1];
                int step = currentNode.getStep();
                if (x >= 0 && x < size && y >= 0 && y < size) {
                    //如果棋格没有越界,并且没有访问过
                    if (chessPanel[x][y] == null) {
                        chessPanel[x][y] = new chessNode(x, y, false, 0, false);
                    }
                    nextNode = chessPanel[x][y];
                    if (!nextNode.isVisited()) {
                        nextNode.setVisited(true);//标记访问过
                        nextNode.setStep(step + 1);//记录步数
                        queue.addLast(nextNode);//入队
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        int n = 0;
        int size = 0;
        int startX = 0, startY = 0, endX = 0, endY = 0;
        Scanner scanner = new Scanner(new BufferedInputStream(System.in));
        n = scanner.nextInt();
        for (int i = 0; i < n; i++) {
            size = scanner.nextInt();//棋盘大小为size*size
            startX = scanner.nextInt();//初始位置x坐标
            startY = scanner.nextInt();//初始位置y坐标
            endX = scanner.nextInt();//目的位置x坐标
            endY = scanner.nextInt();//目的位置y坐标
            chessNode[][] chessPanel = new chessNode[size][size];
            //设置目的位置true
            chessPanel[endX][endY] = new chessNode(endX, endY, false, 0, true);
            //广度优先遍历
            BreadthFirstSearch(startX, startY, chessPanel, size);
            //输出最少步数
            System.out.println(chessPanel[endX][endY].getStep());
        }
    }
}

class chessNode {

    private int x;
    private int y;
    private boolean visited;//标记是否访问过
    private int step;//记录从初始位置到当前棋格的最少步数

    public int getX() {
        return x;
    }

    public chessNode(int x, int y, boolean visited, int step, boolean target) {
        this.x = x;
        this.y = y;
        this.visited = visited;
        this.step = step;
        this.target = target;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }
    private boolean target;

    public boolean isVisited() {
        return visited;
    }

    public void setVisited(boolean visited) {
        this.visited = visited;
    }

    public int getStep() {
        return step;
    }

    public void setStep(int step) {
        this.step = step;
    }

    public boolean isTarget() {
        return target;
    }

    public void setTarget(boolean target) {
        this.target = target;
    }
}
分享到:
评论

相关推荐

    Heyinsen#LeetcodeOrPat#20-1-21-图的深度优先和广度优先遍历-POJ1543-水题1

    水题, 爆搜const int maxn = 105;

    POJ算法题目分类

    * 图的深度优先遍历和广度优先遍历:图的深度优先遍历和广度优先遍历是指遍历图的两种方式,如 poj1860、poj3259、poj1062、poj2253、poj1125、poj2240。 * 最短路径算法:最短路径算法是指计算图中两点之间的最短...

    acm poj300题分层训练

    2. **图算法**:包括图的深度优先遍历、广度优先遍历、最短路径算法、最小生成树算法、拓扑排序、二分图的最大匹配以及最大流的增广路算法。如poj3278、poj2049、poj3083是图遍历的例子,poj1860、poj3259等则是最短...

    poj题目分类

    * 图的深度优先遍历和广度优先遍历:例如 poj1860、poj3259、poj1062、poj2253、poj1125、poj2240。 * 最短路径算法:例如 Dijkstra、Bellman-Ford、Floyd、Heap+Dijkstra,例如 poj1860、poj3259、poj1062、poj...

    poj训练计划.doc

    - 图的深度优先遍历和广度优先遍历:用于探索图的所有节点,如`poj1860, poj3259`。 - 最短路径算法:如Dijkstra算法和Bellman-Ford算法,用于找到两点间的最短路径,如`poj1062, poj2253`。 - 最小生成树算法:...

    ACM常用算法及其相应的练习题 (2).docx

    (2) 广度优先搜索:poj3278, poj1426, poj3126, poj3087, poj3414 (3) 简单搜索技巧和剪枝:poj2531, poj1416, poj2676, 1129 五、动态规划 本部分涵盖了动态规划,包括背包问题、简单DP和其他DP问题。 (1) 背包...

    ACM 比赛 POJ的训练计划,,,非常不错,关键在于坚持

    然后,需要学习图算法,如深度优先遍历、广度优先遍历、最短路径算法和最小生成树算法等。最后,需要学习数据结构,如串、排序、堆和哈希表等。 ACM 比赛 POJ 训练计划旨在帮助选手提高算法和数据结构的能力,涵盖...

    ACM 详解算法目录

    图算法部分涵盖了图的深度优先遍历和广度优先遍历、最短路径算法、最小生成树算法、拓扑排序和二分图的最大匹配等六个方面。例如,POJ1860和POJ3259是最短路径算法的典型例题,而POJ1789和POJ2485则是最小生成树算法...

    POJ题目简单分类(ACM)

    - **深度优先遍历和广度优先遍历**:是图的基本操作,用于搜索图的所有节点。 - **最短路径算法**:包括dijkstra、bellman-ford、floyd和heap+dijkstra,如poj1860等,用于找到节点间的最短距离。 - **最小生成树...

    poj各种分类

    包括深度优先遍历(DFS)和广度优先遍历(BFS),用于探索图的所有节点,是解决许多图问题的基础,如poj1860和poj3259所示。 #### 最短路径算法 Dijkstra算法、Bellman-Ford算法和Floyd算法分别适用于无负权边、有...

    ACM常用算法及其相应的练习题.docx

    * 图的深度优先遍历和广度优先遍历 * 最短路径算法:dijkstra, bellman-ford, floyd, heap+dijkstra + poj1860, poj3259, poj1062, poj2253, poj1125, poj2240 * 最小生成树算法:prim, kruskal + poj1789, poj...

    ACM常用算法及其相应的练习题 (2).pdf

    * 图的深度优先遍历和广度优先遍历:图的深度优先遍历和广度优先遍历是指对图进行遍历的两种常用方法。例题:无。 * 最短路径算法:最短路径算法是指在图中寻找从一个点到另一个点的最短路径的算法。例题:poj1860、...

    北大acm 1915 Knight Moves C++语言源代码

    在本题目中,“北大 ACM JudgeOnline poj1915 Knight Moves”要求解决的是一个经典的骑士行走问题。具体来说,题目背景提到了一位自称无人能及的国际象棋高手Mr. Somurolov,他声称没有人能够像他那样快速地移动骑士...

    acm 分类 北大

    - 深度优先遍历和广度优先遍历:遍历图中的所有节点,如POJ1062。 - 最短路径算法:包括Dijkstra、Bellman-Ford、Floyd和堆优化Dijkstra,如POJ1125和POJ2240。 - 最小生成树算法:Prim和Kruskal算法,如POJ1789...

    POJ1426-Find The Multiple【BFS+同余模】

    【标题】"POJ1426-Find The Multiple【BFS+同余模】"是一道来源于北京大学在线编程平台POJ的算法题目,主要涉及到了广度优先搜索(BFS)与同余模运算的知识点。这道题目要求解决的是寻找一个整数的倍数问题,可能...

    很快速的提高算法能力.pdf

    对于图算法,熟悉深度优先遍历(DFS)和广度优先遍历(BFS)至关重要,它们在 poj1094 和其他题目中有应用。最短路径算法如 dijkstra、bellman-ford、floyd 和 heap+dijkstra 可用于 poj1860 等。最小生成树算法 ...

    POJ题目及答案

    例如,数据结构部分可能包括链表、栈、队列、树、图等经典结构的运用,如二叉树的遍历、图的深度优先搜索和广度优先搜索等;在图论方面,可能会遇到最小生成树、最短路径等问题;动态规划则常用于解决背包问题、最长...

    北大acm试题分类.doc

    1. 图的深度优先遍历和广度优先遍历:在图中遍历节点,如 poj1062。 2. 最短路径算法:dijkstra、bellman-ford、floyd 和 heap+dijkstra,如 poj1860。 3. 最小生成树算法:prim 和 kruskal,例如 poj1789。 4. 拓扑...

Global site tag (gtag.js) - Google Analytics