HDU 5335 || Walk Out || 2015 Multi-University Training Contest 4 简单题

进入hdu 5335 请戳

  1. 题意:
    给n*m的矩阵,每个小单元只能为0或1,求从(0,0)位置出发到(n-1,m-1),求出并且输出走过路径最小二进制数。(去掉多余的前导0)
  2. 思路:
    先bfs找到从(0,0)开始能走到的离(n-1,m-1)最小的单元为1的位置,记录该距离,然后从该距离开始扫“/”对角线,距离减1,继续扫对角线。

    具体做法:
    1).定义is[N][N] 的数组,用于标记,mm用来表示开始扫描的位置。
    2).bfs求出mm的值并且做好标记。
    3).扫描分两种情况:第一次扫描发现有能到达的0,则标记该点的右边和下面的,输出0;否则进行第二次扫描,把能到达的1的右边和下面标记,输出1。扫描完毕,记得还有个换行。

  3. 复杂度:
    时间O(n*m)
    空间O(n*m)
  4. 代码:
/* ***********************************************
Author        :Ilovezilian
Created Time  :2015/8/1 11:08:48
File Name     :1009_2.cpp
 ************************************************ */

#include <bits/stdc++.h>
#define fi(i,n) for(int i = 0; i < n; i ++)
#define fin(i,n1,n2) for(int i = n1; i < n2; i ++)
#define ll long long
#define INF 0x0x7fffffff
using namespace std;
const int N = 1010, mod = 1e9+7;
int n, m, mm;
char s[N][N];
bool vis[N][N];
struct nod{
    int x, y;
};
queue<nod> q;

void bfs()
{
    mm = 0;
    memset(vis, 0, sizeof(vis));
    while(!q.empty()) q.pop();
    int x, y;
    vis[0][0] = 1, q.push((nod){0,0});
    while(!q.empty())
    {
        x = q.front().x, y = q.front().y;
        q.pop();

        //printf("(%d,%d)\n", x, y);
        if(s[x][y] == '1') 
        {
            mm = max(mm,x + y);
            continue;
        }

        if(x-1 >= 0 && !vis[x-1][y]) vis[x-1][y] = 1, q.push((nod){x-1,y});
        if(y-1 >= 0 && !vis[x][y-1]) vis[x][y-1] = 1, q.push((nod){x,y-1});
        if(x+1 < n  && !vis[x+1][y]) vis[x+1][y] = 1, q.push((nod){x+1,y});
        if(y+1 < m  && !vis[x][y+1]) vis[x][y+1] = 1, q.push((nod){x,y+1});
    }
    return;
}

void bfs1()
{
    //printf("[%d,%d]\n", mm, n+m-2);
    for(int i = mm; i < n + m - 1; i ++)
    {
        //printf("i = %d\n", i);
        bool ok = 1;
        int j = (i >= n ? (n - 1) : i), k = i - j;
        //printf(" j = %d, k = %d\n", j, k);
    //  for(j = (i >= n ? (n - 1) : i), k = i - j; j >= 0 && k < m; j-- , k ++) printf("s[%d][%d] = %c vis[%d][%d] = %d\n", j, k, s[j][k], j, k, vis[j][k]);
        for( j = (i >= n ? (n - 1) : i), k = i - j; j >= 0 && k < m; j-- , k ++) if(s[j][k] == '0' && vis[j][k]) 
        {
            if(j+1 < n) vis[j+1][k] = 1;
            if(k+1 < m) vis[j][k+1] = 1;
            ok = 0;
        //  printf("j = %d k = %d\n", j, k);
        }

        if(ok)
        {
            for(j = (i >= n ? n - 1 : i), k = i - j; j >= 0 && k < m; j --, k ++) if(s[j][k] == '1' && vis[j][k]) 
            {
                if(j+1 < n) vis[j+1][k] = 1;
                if(k+1 < m) vis[j][k+1] = 1;
                //printf("j = %d k = %d\n", j, k);
            }
        }
        /*
        */
        printf("%c", ok?'1' : '0');
    }
    printf("\n");
}

void solve()
{
    scanf("%d%d", &n, &m);
    fi(i,n) scanf("%s", s[i]);
    bfs();
    if(vis[n-1][m-1] && s[n-1][m-1] == '0') printf("0\n");
    else bfs1();
}

int main()
{
    //freopen("1009.in","r",stdin);
    //freopen("my_2.out","w",stdout);
    int cas;
    scanf("%d", &cas);
    while(cas --) solve();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章