HDU 5335 Walk Out

题意:在一个只有0和1的矩阵里,从左上角走到右下角, 每次可以向四个方向走,每个路径都是一个二进制数,求所有路径中最小的二进制数。

解法:先bfs求从起点能走到离终点最近的0,那么从这个点起只向下或向右走就可以获得位数最少的二进制数,然后贪心的想,如果后或下有0就一定走0,没0就把1都看一遍,以之前搜到的0做起点,一层一层遍历可行路径,直到终点。

代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long

using namespace std;

int n, m;
bool vis[1005][1005];
char maze[1005][1005];
struct node
{
    int x, y;
    node(int x, int y) : x(x), y(y) {}
    node() {}
};
queue <node> q;
vector <node> v[2];
int maxn = 0;
int dir[4][2] = {0, 1, 1, 0, 0, -1, -1, 0};
void bfs()
{
    q.push(node(0, 0));
    vis[0][0] = 1;
    if(maze[0][0] == ‘1‘)
    {
        q.pop();
        return ;
    }
    while(!q.empty())
    {
        node tmp = q.front();
        q.pop();
        for(int i = 0; i < 4; i++)
        {
            int tx = tmp.x + dir[i][0], ty = tmp.y + dir[i][1];
            if(tx >= 0 && tx < n && ty >= 0 && ty < m && !vis[tx][ty] && maze[tx][ty] == ‘0‘)
            {
                vis[tx][ty] = 1;
                maxn = max(maxn, tx + ty);
                q.push(node(tx, ty));
            }
        }
    }
}
int main()
{
    int T;
    while(~scanf("%d", &T))
    {
        while(T--)
        {
            maxn = 0;
            memset(vis, 0, sizeof vis);
            for(int i = 0; i < 2; i++)
                v[i].clear();
            scanf("%d%d", &n, &m);
            for(int i = 0; i < n; i++)
                scanf("%s", maze[i]);
            bfs();
            for(int i = 0; i < n; i++)
            {
                for(int j = 0; j < m; j++)
                {
                    if(vis[i][j] && (i + j == maxn))
                        v[0].push_back(node(i, j));
                }
            }
            int cnt = 0;
            int flag2 = 1;
            string ans;
            if(maze[0][0] == ‘1‘)
                ans += ‘1‘;
            else
                ans += ‘0‘;
            while(1)
            {
                int len = v[cnt].size();
                for(int i = 0; i < len; i++)
                {
                    if((v[cnt][i].x == n - 1) && (v[cnt][i].y == m - 1))
                    {
                        flag2 = 0;
                        break;
                    }
                    for(int j = 0; j < 2; j++)
                    {
                        int tx = v[cnt][i].x + dir[j][0], ty = v[cnt][i].y + dir[j][1];
                        if(tx >= 0 && tx < n && ty >= 0 && ty < m && !vis[tx][ty] && maze[tx][ty] == ‘0‘)
                        {
                            vis[tx][ty] = 1;
                            v[!cnt].push_back(node(tx, ty));
                        }
                    }
                }
                if(!flag2) break;
                if(v[!cnt].size() == 0)
                {
                    ans += ‘1‘;
                    for(int i = 0; i < len; i++)
                    {
                        for(int j = 0; j < 2; j++)
                        {
                            int tx = v[cnt][i].x + dir[j][0], ty = v[cnt][i].y + dir[j][1];
                            if(tx >= 0 && tx < n && ty >= 0 && ty < m && !vis[tx][ty] && maze[tx][ty] == ‘1‘)
                            {
                                vis[tx][ty] = 1;
                                v[!cnt].push_back(node(tx, ty));
                            }
                        }
                    }
                }
                else
                    ans += ‘0‘;
                v[cnt].clear();
                cnt = !cnt;
            }
            int len = ans.size();
            int flag1 = 1;
            for(int i = 0; i < len; i++)
            {
                if((ans[i] == ‘0‘) && flag1) continue;
                flag1 = 0;
                printf("%c", ans[i]);
            }
            if(flag1)
                printf("0");
            puts("");
        }
    }
    return 0;
}

不知道为什么一直MLE……换了个写法重写了一下才过……

时间: 2024-11-01 21:37:01

HDU 5335 Walk Out的相关文章

hdu 5335 Walk Out (搜索)

题目链接: hdu 5335 Walk Out 题目描述: 有一个n*m由0 or 1组成的矩形,探险家要从(1,1)走到(n, m),可以向上下左右四个方向走,但是探险家就是不走寻常路,他想让他所走的路线上的0/1组成的二进数最小,现在要为矫情无比的探险家找最优路径咯. 解题思路: 对于二进制数,前导零是对数字大小没有任何影响的.当到不得不走1的时候就只能向下,或者向右走了.所以先搜索出来一直走零,能走到的最靠近终点的位置,然后在类似搜索,找出最优路径. 1 #include <queue>

HDU 5335 Walk Out (搜索+贪心,超详解)经典

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5335 题面: Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2355    Accepted Submission(s): 459 Problem Description In an n?m maze, the righ

HDU 5335 Walk Out(多校)

Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2912    Accepted Submission(s): 599 Problem Description In an n∗m maze, the right-bottom corner is the exit (position (n,m) is the exit).

HDU 5335——Walk Out——————【贪心】

Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1292    Accepted Submission(s): 239 Problem Description In an n∗m maze, the right-bottom corner is the exit (position (n,m) is the exit).

HDU 5335 Walk Out(Bfs搜索字典序最小的最短路)

 题意:nXm的地图, 问通过四个方向从(1,1)走到(1000,1000)所经过的最小二进制序列是多少,忽略前缀0. 思路:首先如果起点为0,那么我们bfs搜索和起点0联通的为0的连通块,这样我们第一步肯定是从与这个连通块相邻的且与重点最近的地方出发. 将所有可能起点加入队列,在bfs一遍找到字典序最小的那条路就是答案, 在这里可以用两个vector类型容器,一个是q2存储所有节点值存为0的结点, 另一个q3存储节点值为1的结点. 那么如果q2不为空那么也就是有可以走零,那么就从这里面选,

HDU 5335 Walk Out (BFS,技巧)

题意:有一个n*m的矩阵,每个格子中有一个数字,或为0,或为1.有个人要从(1,1)到达(n,m),要求所走过的格子中的数字按先后顺序串起来后,用二进制的判断大小方法,让这个数字最小.前缀0不需要输出!! 思路:主要考虑的是BFS解决. 如果grid[1,1]=1,那么这个二进制的位数也就定下来了,是n+m-1,很好解决,每个格子就只能往下或者往右,否则长度一定超过n+m+1,必定不是最优. 如果grid[1,1]=0,那么可能会出现绕了一个S型到终点的结果为0而已.所以不能用老办法,要先预处理

hdu 5335 Walk Out(bfs+寻找路径)

Problem Description In an n∗m maze, the right-bottom corner is the exit (position (n,m) is the exit). In every position of this maze, there is either a 0 or a 1 written on it. An explorer gets lost in this grid. His position now is (1,1), and he want

HDU 5335 多校第4场 1009 Walk Out

Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1794    Accepted Submission(s): 340 Problem Description In an n?m maze, the right-bottom corner is the exit (position (n,m) is the exit)

HDU 5001 Walk(鞍山网络赛E题)

HDU 5001 Walk 题目链接 思路:枚举每个要经过的点,然后进行状态转移,状态为dp[i][j],状态表示当前在j的点,已经走了i步,每次转移的时候,不从这个枚举的点出发,这样就可以求出所有路径经过该点的概率p, 然后1 - p就是不经过的答案 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; con