zoukankan      html  css  js  c++  java
  • 2017年上海金马五校程序设计竞赛:Problem B : Sailing (广搜)

    Description

    Handoku is sailing on a lake at the North Pole. The lake can be considered as a two-dimensional square plane containing N × N blocks, which is shown in the form of string containing '*' and '#' on the map.

      • : a normal block;
    • : a block containing pack ice.

    Handoku is at (1, 1) initially, and his destination is (N, N). He can only move to one of the four adjacent blocks. Sailing around pack ice is dangerous and stressful, so he needs power to remain vigilant. That means if he moves from a '*' block to a '#' block or moves from a '#' block to any another block, he needs to consume 1 unit power. In other cases, he can enjoy the scene on his boat without consuming any power.

    Now Handoku wants to know how many units power will be consumed at least during his sailing on the lake.

    Input

    There are several test cases (no more than 20).

    For each test case, the first line contains a single integer N (3 ≤ N ≤ 50), denoting the size of the lake. For the following N lines, each line contains a N-length string consisting of '*' and '#', denoting the map of the lake.

    Output

    For each test case, output exactly one line containing an integer denoting the answer of the question above.

    Sample Input

    3
    **#
    **#
    *#*
    3
    ##*
    #*#
    ###
    4
    **##
    #**#
    ##**
    ###*
    

    Sample Output

    2
    4
    0
    

    分析:

    题意:给出一个NN的地图,起点(1,1),终点(n,n),每次只可以向四个方向走一个格子,地图只由两个字符组成 ''和 '#'。

    从字符 ‘*’ 走到字符'#'需要花费1秒时间,从字符'#'走到其他位置(无论那个位置字符是什么)也要花费1秒时间。其他情况不花费时间。求从(1,1)走到(n,n)花费的最小时间。

    解题思路:

    原来vis数组刷成0,走过的都标1。为了走回头路,新的代码把vis刷成-1,然后对于走过的点,vis放置走到该点的最小时间,这样走到一个点,如果这个点没有访问过,即对应的vis是-1,则该点一定要进队,然后vis变成到达该点的时间。对于已经当过的点,vis数组里面存放的是它上一次到达这个点的最小时间,现在又到了这个点,如果时间比vis里面的时间短,则更新vis,该点再次入队。

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    using namespace std;
    char Map[52][52];
    int vis[52][52];
    int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}}; ///搜索方向上右下左
    int n;
    struct Node
    {
        int x;
        int y;
        int power;///能量
        friend bool operator < (Node a,Node b)
        {
            return a.power>b.power;///能量从小打大
        }
    };
    int bfs()
    {
        Node now,next;
        now.x = 1;
        now.y = 1;
        now.power = 0;
        vis[now.x][now.y] = now.power;
        priority_queue<Node>qu;
        qu.push(now);
        while(!qu.empty())
        {
            now = qu.top();
            qu.pop();
            if(now.x == n && now.y == n)///达到终点
                return now.power;
            for(int i = 0; i < 4; i++)
            {
                next.x = now.x + dir[i][0];
                next.y = now.y + dir[i][1];
                next.power = now.power;
                if(next.x<1||next.x>n||next.y<1||next.y>n) continue;
                if(Map[now.x][now.y]=='*')
                {
                    if(Map[next.x][next.y]=='#')
                        next.power++;
                }
                else
                {
                    next.power++;
                }
                if(vis[next.x][next.y]==-1)///没有走过
                {
                    vis[next.x][next.y] = next.power;///直接赋值就行了
                    qu.push(next);
                }
                else
                {
                    if(next.power<vis[next.x][next.y])///以前走过,但是现在的时间花费比较小
                    {
                        vis[next.x][next.y] = next.power;///更改时间花费
                        qu.push(next);
                    }
                }
            }
        }
        return -1;
    }
    int main()
    {
        while(~scanf("%d",&n))
        {
            getchar();
            ///输入地图
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                {
                    scanf(" %c",&Map[i][j]);
                }
            memset(vis,-1,sizeof(vis));
            int ans = bfs();
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    vue-quill-editor的自定义设置字数长度方法和显示剩余数字
    element-ui表格show-overflow-tooltip="true",鼠标移上去显示的宽度设置
    vue + elementui表单重置 resetFields问题(无法重置表单)
    element ui表单验证,validate与resetFields的使用你知道哪些
    前端下载文件(GET、POST方法)
    vue中使用elementui里的table时,需求是前面的勾选框根据条件判断是否可以勾选设置
    流体力学笔记 第一章 向量场的概念及运算
    Gersgorin定理
    奇异值分解的证明和直观理解
    2020机器学习学习笔记
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6941130.html
Copyright © 2011-2022 走看看