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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章