Sicily 1321. Robot 解题报告

1321_Robot

题目链接:

http://soj.me/1321

题目大意:

给一个矩阵,每一个点上面的数字表示走到该点需要的花费,找出给定起点到终点的最小总花费

思路:

每个格子看作一个结点,花费可以看作从上一个点走到这个点的路程,那么这道题就是典型的最短路径问题,可以用Dijkstra算法解决。一开始直接套用整个算法,将每个新的结点加入到集合S中的时候,更新所有不在集合中的结点的最短路径并排序以便下一次找出路径最短的结点,结果超时。 这里使用了优先队列q来优化,q里面放入每次可以加入到集合S里面的结点。整个流程类似Dijkstra算法,需要注意的地方是这里每次将一个结点加入S时只是简单的将相邻的4个结点放入到候选队列q中,所以q里面可能会出现重复的或者已经找到的结点,所以每次在队列中先将顶部已经完成的结点去掉。

代码:

#include <iostream>
#include <queue>
using namespace std;

class Point {
public:
    int x;
    int y;
    int distance;
    Point(int xx = 0, int yy = 0, int dd = 0) {
        x = xx;
        y = yy;
        distance = dd;
    }
    friend bool operator<(const Point &p1, const Point &p2) { //重载小于号这样优先队列默认为最小堆
        return p1.distance > p2.distance;
    }
};
int move_x[4] = { -1, 1, 0, 0 }; //上下左右
int move_y[4] = { 0, 0, -1, 1 };

int main() {
    int numTestcases;
    cin >> numTestcases;
    int numRow, numCol;
    int matrix[101][101]; //记录每个点的油耗
    int start_x, start_y, end_x, end_y; //出发点和目标点坐标
    bool included[101][101]; //Dijkstra算法里面的集合S,里面的每个结点到源结点的最短路径已经找到
    while (numTestcases--) {
        cin >> numRow >> numCol;
        for (int row = 1; row <= numRow; ++row) {
            for (int col = 1; col <= numCol; ++col) {
                cin >> matrix[row][col];
                included[row][col] = false;
            }
        }
        cin >> start_x >> start_y >> end_x >> end_y;

//      included[start_x][start_y] = true; //将源结点放入集合中
        priority_queue<Point> q; //放入目前最有可能加入到集合S中的点
        q.push(Point(start_x, start_y, matrix[start_x][start_y]));
        while (!(q.top().x == end_x && q.top().y == end_y)) { //队列顶部为目标时停止,这时候该点的distance值已经是最短路径,并准备放入到集合S中,停止循环并输出即可
            while (included[q.top().x][q.top().y]) {
                q.pop();
            }
            //每次取出离集合S距离最近的一个点加入到S中
            Point cur = q.top();
            included[cur.x][cur.y] = true;
            for (int i = 0; i < 4; ++i) {
                int x = cur.x + move_x[i];
                int y = cur.y + move_y[i];
                if (x >= 1 && x <= numRow && y >= 1 && y <= numCol
                        && !included[x][y])
                    q.push(Point(x, y, cur.distance + matrix[x][y]));
            }
        }
        cout << q.top().distance << endl;
    }
    return 0;
}
时间: 2024-08-26 19:24:22

Sicily 1321. Robot 解题报告的相关文章

Sicily 1090. Highways 解题报告

题目链接:Sicily 1090 思路: 简单的最小生成树问题,这里用prim算法即可.用visited数组记录每个结点是否已经被访问,即是否已经在最小生成树中.每次从不在最小生成树中的结点中取出一个key值最小的结点放入生成树中,key值表示结点到已经在生成树中点集合的最小距离.每次加入一个结点后更新与它相邻的结点的key值. 代码: #include <iostream> #include <queue> #include <stdio.h> #include &l

Sicily 1321. Robot

1321. Robot Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description Karell Incorporated has designed a new exploration robot that has the ability to explore new terrains, this new robot can move in all kinds of terrain, it only needs more fue

Sicily 1031. Campus 解题报告

1031_Campus 题目链接: http://soj.me/1031 题目大意: 给出四个校区的一些地点之间的距离,地点名用字符串来表示,问某两个地点之间的最短路径长度,典型的单源最短路径题目 思路: 单源最短路径问题可以用dijkstra算法实现,这道题比较麻烦的是用字符串来表示地点,我用的处理方法是建立map得到地点名字到序号的映射,对于每个新输入的地点名字,先在map里面查找是否存在,如果不存在就绑定一个新的序号.地点之间的距离用邻接矩阵来存放. 代码: #include <iostr

Sicily 1308. Dependencies among J 解题报告

题目:1308. Dependencies among J 思路: 比较简单的一道题,要知道m最早完成的时间,只需要找出所有需要在m之前完成的工作,将它们的完成时间加起来即可.这里使用vector的数组存储每个结点的邻接点,从结点m开始,依次宽度优先搜索m的每个邻接点...数组visited记录每个结点是否被访问过,遇到已经访问过的结点直接跳过. 读取的时候一开始没有找到解决办法,要读取一行的数字,并且要判断是否换行,可以首先读取第一个数即完成时间,然后用getchar读取一个字符,如果是'\n

Sicily 1350. Piggy banks 解题报告

题目:1350. Piggy banks 思路: 首先把每个钥匙的位置存进key_positions[]中,然后从第一个bank开始,用不同的color给它们分组.比如第一个bank的钥匙在第二个bank中,那么可以直接先开第二个,第二个钥匙在第四个bank中,同样可以先开第四个,以此类推,直到某个钥匙出现在前面的同一组的某个bank中则需要打破一个.visited数组初始化为0,然后访问过后标记为颜色的编号.第21行visited[cur] == color只有找到颜色相同即在同一组的才需要打

leetCode解题报告5道题(十一)

题目一:Subsets Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2]

解题报告 之 POJ3057 Evacuation

解题报告 之 POJ3057 Evacuation Description Fires can be disastrous, especially when a fire breaks out in a room that is completely filled with people. Rooms usually have a couple of exits and emergency exits, but with everyone rushing out at the same time

hdu 1541 Stars 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有比它低层(或者同层)的或者在它左手边的星星数决定.计算出每个等级(0 ~ n-1)的星星各有多少颗. 我只能说,题目换了一下就不会变通了,泪~~~~ 星星的分布是不是很像树状数组呢~~~没错,就是树状数组题来滴! 按照题目输入,当前星星与后面的星星没有关系.所以只要把 x 之前的横坐标加起来就可以了

【百度之星2014~初赛(第二轮)解题报告】Chess

声明 笔者最近意外的发现 笔者的个人网站http://tiankonguse.com/ 的很多文章被其它网站转载,但是转载时未声明文章来源或参考自 http://tiankonguse.com/ 网站,因此,笔者添加此条声明. 郑重声明:这篇记录<[百度之星2014~初赛(第二轮)解题报告]Chess>转载自 http://tiankonguse.com/ 的这条记录:http://tiankonguse.com/record/record.php?id=667 前言 最近要毕业了,有半年没做