hdu 5335 Walk Out【搜索】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5335

题意:给你一个n*m的0 1矩阵,要求你从(1,1)坐标开始走到(n,m)要求是的路径的上组成的01序列二进制表示最小,前导0可以忽略。

思路:只能向下或右走,否则二进制表示长度增加,必然增大。首先找到从(1,1)能走到的最远的0是多远,从这个或这些点再向(n,m)走。注意:dfs会爆栈,要手动加栈。

code:

#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <string>
#include <assert.h>
#pragma comment(linker,"/STACK:1024000000,1024000000") 

using namespace std;

const int MAXN = 1010;

int n, m;
char s[MAXN][MAXN];
int tot;
int c[MAXN][MAXN];
int f[MAXN][MAXN];//标记s[i][j]是否为 0

void dfs(int x, int y)
{
    if (x < 1 || x > n || y < 1 || y > m) return;
    if (c[x][y]) return;
    c[x][y] = 1;
    if (s[x][y] == '1') return;
    f[x][y] = 1;
    tot = max(tot, x + y);
    dfs(x - 1, y);
    dfs(x + 1, y);
    dfs(x, y - 1);
    dfs(x, y + 1);
}

int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        memset(c, 0, sizeof(c));
        memset(f, 0, sizeof(f));
        tot = 1;

        scanf("%d %d",&n,&m);
        for (int i = 1; i <= n; i++)
            scanf("%s", s[i] + 1);
        dfs(1, 1);
        //printf("tot is :%d\n", tot);
        if (tot == n + m)
        {
            printf("0\n");
            continue;
        }
        if (tot == 1)
        {
            tot = 2;
            f[1][1] = 1;
            printf("1");
        }
        for (int i = tot; i < n + m; i++)
        {
            int ok = 1;
            for (int j = max(1, i - m); j <= min(n, i - 1); j++)
            {
                if (f[j][i - j])
                {
                    int x, y;
                    if (j < n) x = s[j + 1][i - j] - '0';//向右走
                    else x = 1;
                    if (i - j < m) y = s[j][i - j + 1] - '0';//向下走
                    else y = 1;
                    ok = min(ok, min(x, y));
                }
            }
            for (int j = max(1, i - m); j <= min(n, i - 1); j++)
            {
                if (f[j][i - j])
                {
                    int x, y;
                    if (j < n) x = s[j + 1][i - j] - '0';//向右走
                    else x = 1;
                    if (i - j < m) y = s[j][i - j + 1] - '0';//向下走
                    else y = 1;
                    if (x == ok) f[j + 1][i - j] = 1;
                    if (y == ok) f[j][i - j + 1] = 1;
                }
            }
            printf("%d",ok);
        }
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(hdu 5335 Walk Out【搜索】)