• P3956 棋盘


    题目描述

    有一个m imes mm×m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。

    任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的), 你只能向上、 下、左、 右四个方向前进。当你从一个格子走向另一个格子时,如果两个格子的颜色相同,那你不需要花费金币;如果不同,则你需要花费 1个金币。

    另外, 你可以花费 2 个金币施展魔法让下一个无色格子暂时变为你指定的颜色。但这个魔法不能连续使用, 而且这个魔法的持续时间很短,也就是说,如果你使用了这个魔法,走到了这个暂时有颜色的格子上,你就不能继续使用魔法; 只有当你离开这个位置,走到一个本来就有颜色的格子上的时候,你才能继续使用这个魔法,而当你离开了这个位置(施展魔法使得变为有颜色的格子)时,这个格子恢复为无色。

    现在你要从棋盘的最左上角,走到棋盘的最右下角,求花费的最少金币是多少?


    本题是较为基础的搜索,代码入下:
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define inf 0x7fffffff
    using namespace std;
    int fx[4] = {-1, 0, 1, 0}; 
    int fy[4] = {0, -1, 0, 1}; 
    int f[110][110];
    int mp[110][110]; 
    int m, n, ans = inf;
    void dfs(int x, int y, int sum, bool frog)
    {
        if(x < 1 || y < 1 || x > m || y > m) return;
        if(sum >= f[x][y]) return;
        f[x][y] = sum;
        if(x==m && y==m) 
        {
            if(sum < ans) ans = sum;  //更新最小值
            return;
        }
        for(int i = 0; i < 4; ++i)
        {
            int xx = x + fx[i];
            int yy = y + fy[i];
            if(mp[xx][yy]) //如果有颜色
            {
                if(mp[xx][yy] == mp[x][y]) //如果颜色一样,无需花费
                     dfs(xx, yy, sum, false); 
                else dfs(xx, yy, sum+1, false);  //如果颜色不一样,花费一枚金币
            }  
            else  //如果无颜色
            {
                if(!frog)  //判断是否使用了魔法
                {
                    mp[xx][yy] = mp[x][y]; 
                    dfs(xx, yy, sum+2, true);  //标记为true 
                    mp[xx][yy] = 0;  //回溯
                }
            }
        }
    }
    int main()
    {
        memset(f, 0x7f, sizeof(f));
        scanf("%d %d", &m, &n);
        for(int i = 1; i <= n; ++i)
        {
            int x, y, c;
            scanf("%d %d %d", &x, &y, &c);
            mp[x][y] = c + 1;
        }
        dfs(1, 1, 0, false);
        printf("%d", ans==inf ? -1 : ans);
        return 0;
    }

    本题使用了深度优先搜索,我不会广搜,每进行一次搜索就更新一遍最小值,最后输出该值。

    代码与一般的深搜差别不是很大,一些重要的地方已经做了注释。相信大家都能理解。

  • 相关阅读:
    在operator =中要处理“自我赋值”
    delete指针以后应赋值为NULL
    【转】C++对成员访问运算符->的重载
    【转】浅析SkipList跳跃表原理及代码实现
    【KakaJSON手册】05_JSON转Model_05_动态模型
    【KakaJSON手册】04_JSON转Model_04_值过滤
    【KakaJSON手册】03_JSON转Model_03_key处理
    【KakaJSON手册】02_JSON转Model_02_数据类型
    【KakaJSON手册】01_JSON转Model_01_基本用法
    利用eclipse调试JDK源码
  • 原文地址:https://www.cnblogs.com/Na2S2O3/p/13408828.html
Copyright © 2020-2023  润新知