• poj 3009 Curling 2.0 (dfs)


    题目链接

    http://poj.org/problem?id=3009

    题意:

    给出n*m的图,给出起点和终点,里面有墙,有一个球从起点出发,只能走上下左右四个方向,如果即将撞墙会在墙前停下,墙会被破坏,然后可以重新选择方向,这样算走了一步。

    如果能在十步内走到终点(终点不一定刚好停下时达到,如果移动中遇到,也算是走到终点),输出达到终点的最小结果。

    如果不能走到终点或者大于十步才能走到,输出-1。

    分析:

    注意一下几点:

    1.不能越界

    2.必须周围不是墙才能走,不能直接把墙破坏,至少要走一步才能把墙破坏。

    3.中途遇到终点就可以马上停下。

    4.如果该方向路上没有墙直接走出了界,那么就不能选择这个方向(直接return)。

    很久没写dfs,感觉写这种程度的搜索都很费力,建议以后写搜索前先分析好,不要边写边想。

    代码注意以下几点:

    1.dfs求最优答案最好把最优答案定为全局变量,然后在搜到终点时更新答案

    2.尽量精简以下代码,用一个数组去表示方向。

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <vector>
    #define inf 99999999
    using namespace std;
    int w,h;
    int G[30][30];int beginx, beginy, endx, endy;
    int ans;
    void dfs(int x, int y, int step)
    {
    
        if(step > 10)
        {
            return;
        }
        int tx,ty;
        if(G[x][y+1] != 1 && y + 1 <= w)
        {
            tx = x; ty = y;
            while(G[tx][ty]==0 && ty + 1<=w)
            {
                ty++;
                if(G[tx][ty] == 3)
                {
                    ans = min(step,ans);
                    return;
                }
            }
    //        将碰撞的砖块化为0,回溯时候再化为1
            if(G[tx][ty] == 1)
            {
                G[tx][ty] = 0;
                dfs(tx,ty-1,step+1);
                G[tx][ty] = 1;
            }
        }
    
        if(G[x-1][y] != 1 && x-1 >= 1)
        {
            tx = x; ty = y;
            while(G[tx][ty]==0 && tx-1>=1)
            {
                tx--;
                if(G[tx][ty] == 3)
                {
                    ans = min(step,ans);
                    return;
                }
            }
            if(G[tx][ty] == 1)
            {
                G[tx][ty] = 0;
                dfs(tx+1,ty,step+1);
                G[tx][ty] = 1;
            }
        }
    
        if(G[x][y-1] != 1 && y-1 >= 1)
        {
    
            tx = x; ty = y;
            while(G[tx][ty]==0 && ty-1>=1)
            {
                ty--;
                if(G[tx][ty] == 3)
                {
                    ans = min(step,ans);
                    return;
                }
            }
            if(G[tx][ty] == 1)
            {
                G[tx][ty] = 0;
                dfs(tx,ty+1,step+1);
                G[tx][ty] = 1;
            }
        }
    
        if(G[x+1][y] != 1 && x+1 <= h)
        {
    
            tx = x; ty = y;
            while(G[tx][ty]==0 && tx+1 <= h)
            {
                tx++;
                if(G[tx][ty] == 3)
                {
                    ans = min(step,ans);
                    return;
                }
            }
            if(G[tx][ty] == 1)
            {
                G[tx][ty] = 0;
                dfs(tx-1,ty,step+1);
                G[tx][ty] = 1;
            }
        }
    
    }
    int main()
    {
        while(scanf("%d %d", &w, &h) && w != 0 && h != 0)
        {
    
            memset(G,-1,sizeof(G));
            for(int i = 1; i <= h; i++)
            {
                for(int j = 1; j <= w; j++)
                {
                    int t;
                    scanf("%d", &t);
                    if(t== 2)
                    {
                        beginx = i;
                        beginy = j;
                        G[i][j] = 0;
                    }
                    else if(t == 3)
                    {
                        endx = i;
                        endy = j;
                        G[i][j] = t;
                    }
                    else G[i][j] = t;
                }
            }
            ans = inf;
            dfs(beginx, beginy, 1);
            if(ans == inf)
            {
                printf("-1
    ");
            }
            else printf("%d
    ",ans);
        }
    }

     贴一个别人写的86行代码,学习一下dfs的代码风格。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    const int Max = 20 + 10;
    int map[Max][Max];
    int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}}; //0上,1左,2下,3右 
    int flag; //标记是否找到解
    int minStep; 
    int w,h;
    void dfs(int x, int y, int step)
    {
     
        int nx,ny;
        int tx,ty;
        int px,py;
        if(step > 10)
        {
            return;
        }
        if(map[x][y] == 3)
        {
     
            minStep = min(minStep, step); 
            return;
        }
        for(int i=0; i<4; i++)
        {
            tx = x + dir[i][0];
            ty = y + dir[i][1];
            nx = x;
            ny = y;
         
            while(tx >= 0 && tx < h && ty >= 0 && ty < w && map[tx][ty] != 1) //预判下一步
            {
                nx += dir[i][0];
                ny += dir[i][1];
     
                if(map[nx][ny] == 3) 
                {
     
                    minStep = min(minStep, step); 
                    return;
                }
    
                tx = nx + dir[i][0];
                ty = ny + dir[i][1];
    
                 if(tx < 0 || tx >= h || ty < 0 || ty >= w) //忘记加这句就会错!! 
                      break; //如果下一个位置越界,就直接break跳出,不进行后面的深搜,越界会直接跳到方向循环中,进行改变方向~ 
                if(map[tx][ty] == 1) //没有越界就要判断是不是遇到墙了,遇到墙就停止滑动,开始进行深搜 
                {
                    map[tx][ty] = 0; //消除障碍 
                    dfs(nx, ny, step+1);
                    map[tx][ty] = 1; //重建障碍 
                }
            }
            
        }
    }
    int main()
    {
        int sx,sy;
        while(scanf("%d %d",&w,&h) != EOF && w != 0 && h != 0)
        {
            minStep = 10000;
            for(int i=0; i<h; i++)
            {
                for(int j=0; j<w; j++)
                {
                    scanf("%d",&map[i][j]);
                    if(map[i][j] == 2) //起点 
                    {
                        sx = i;
                        sy = j;
                    }
                }
            }
            dfs(sx, sy, 1); 
            if(minStep == 10000)
                cout<<"-1"<<endl;
            else
                cout<<minStep<<endl;
        }
        return 0;
    }

     

  • 相关阅读:
    高斯模糊原理,算法
    SIFT算法详解
    第五章:状态图
    ANTLR4权威指南
    第八章:包图,组件图,部署图
    棋盘n皇后问题-递归
    普通页面引入React(使用和不使用JSX)
    浏览器环境
    DevTool-Network
    优化浏览器渲染
  • 原文地址:https://www.cnblogs.com/Jadon97/p/6804384.html
Copyright © 2020-2023  润新知