HDU - 5335

首先谢谢大佬的博客,让我终于在第30多次提交的时候AC了

http://www.cnblogs.com/mypride/p/4693712.html?tvd

 

不得不说,真的恶心

In an nmn∗m maze, the right-bottom corner is the exit (position (n,m)(n,m) is the exit). In every position of this maze, there is either a 00 or a 11 written on it. 

An explorer gets lost in this grid. His position now is (1,1)(1,1), and he wants to go to the exit. Since to arrive at the exit is easy for him, he wants to do something more difficult. At first, he'll write down the number on position (1,1)(1,1). Every time, he could make a move to one adjacent position (two positions are adjacent if and only if they share an edge). While walking, he will write down the number on the position he's on to the end of his number. When finished, he will get a binary number. Please determine the minimum value of this number in binary system.

InputThe first line of the input is a single integer T (T=10)T (T=10), indicating the number of testcases. 

For each testcase, the first line contains two integers nn and m (1n,m1000)m (1≤n,m≤1000). The ii-th line of the next nn lines contains one 01 string of length mm, which represents ii-th row of the maze.
OutputFor each testcase, print the answer in binary system. Please eliminate all the preceding 00 unless the answer itself is 00 (in this case, print 00 instead).Sample Input

2
2 2
11
11
3 3
001
111
101

Sample Output

111
101

思路:先把前导0都遍历掉,然后选出离终点最近的点(此时长度最短),然后斜向推向终点。。。就是要知道每一斜向都代表某一位上的数字。这一格能从左边或者上边过来。
如果上一个斜向有0,且左边或者上边存在0,那么这一格就能到达,否则不能到达。
如果上一个斜向没有0,那么这一格就都能到达。。。有点dp的味道啊
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack>

using namespace std;

typedef long long LL;
const int INF = 0x3f3f3f3f;
const int MAXN = 1005;
const int MOD = 1e9 + 7;

#define MemI(x) memset(x, -1, sizeof(x))
#define Mem0(x) memset(x, 0, sizeof(x))
#define MemM(x) memset(x, 0x3f, sizeof(x))

int n, m, dis[][2] = {0, 1, 1, 0, 0, -1, -1, 0};
char mp[MAXN][MAXN];
int vis[MAXN][MAXN], len;
struct Node
{
    int x, y;
};
queue<Node> q;

//找出前导0
bool bfs()
{
    int x, y, i, j, k;
    Node t;
    t.x = 0, t.y = 0;
    q.push(t);
    vis[0][0] = 1;
    if(mp[0][0] == '1')
    {
        printf("1");
        return false;
    }
    while(!q.empty())
    {
        x = q.front().x, y = q.front().y;
        q.pop();
        if(x == n - 1 && y == m - 1)
            return true;
        for(k = 0;k < 4;++k)
        {
            i = x + dis[k][0], j = y + dis[k][1];
            if(i >= 0 && j >= 0 && i < n && j < m && !vis[i][j] && mp[i][j] == '0')
            {
                len = max(len, i + j);
                //这里 vis 放在上面会超时
                vis[i][j] = 1;
                t.x = i, t.y = j;
                q.push(t);
            }
        }
    }
    return false;
}

//斜向递推
void solve()
{
    int i, j, k, t;
    for(i = len + 1;i <= m + n - 2;++i)
    {
        k = 0, t = 2;
        if(i >= n)
            k = i - n + 1;
        //这里不对会 Runtime Error,说多了都是泪
        for(j = k;j < m && j <= i;++j)
        {
            //这里看左上两个格子
            if((i - j - 1 >= 0 && j >= 0 && i - j < n && vis[i - j - 1][j]) ||
               (i - j >= 0 && j - 1>= 0 && i - j < n && vis[i - j][j - 1]))
                t = min(t, mp[i - j][j] - '0');
        }
        printf("%d", t);
        for(j = k;j < m && i - j < n;++j)
        {
            if((i - j - 1 >= 0 && j >= 0 && i - j < n && vis[i - j - 1][j]) ||
               (i - j >= 0 && j - 1>= 0 && i - j < n && vis[i - j][j - 1]))
                if(mp[i - j][j] - '0' == t)
                vis[i - j][j] = 1;
        }
    }
    printf("\n");
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        Mem0(vis);
        len = 0;
        while(!q.empty())
            q.pop();
        scanf("%d%d", &n, &m);
        for(int i = 0;i < n;++i)
            scanf("%s", mp[i]);
        if(bfs())
            printf("0\n");
        else
            solve();
    }
    return 0;
}
/*
如果是自己照思路写的,试试这数据
1 1
0
1 1
1
输出应该是
0
1
*/

 

 
 
posted @ 2018-08-03 16:02  谁知道你啊啊啊  阅读(117)  评论(0编辑  收藏  举报