HDU 5335 Walk Out BFS 比较坑

H - H
Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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 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). 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.
 

Input

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

For each testcase, the first line contains two integers n and m \ (1 \le n, m \le 1000). The i-th line of the next n lines contains one 01 string of length m, which represents i-th row of the maze.
 

Output

For each testcase, print the answer in binary system. Please eliminate all the preceding 0 unless the answer itself is 0 (in this case, print 0instead).
 

Sample Input

2 2 2 11 11 3 3 001 111 101
 

Sample Output

111 101
给定一个由0和1组成的棋盘,从左上角走到右下角路径(上下左右四种行走方式)组成二进制数问最小的是什么 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
#define MM(a,b); memset(a,b,sizeof(a));
int n,m,step,res,ans[1000000+10],vis[1003][1003],cnt=0,a[1010][1010];
int dx[5]={0,1,0,-1};
int dy[5]={1,0,-1,0};
int flag[1000+1000+100];
char s[1003][1003];

struct node{
   int x,y;
};
queue<node> q;

bool legal(int x,int y)
{
   return x>=1&&x<=n&&y>=1&&y<=m;
}

void bfs()
{
   q.push((node){1,1});
   vis[1][1]=1;
   while(q.size())
   {
       int x=q.front().x,y=q.front().y;q.pop();
       for(int i=0;i<4;i++)
       {
           int tx=x+dx[i],ty=y+dy[i];
           if(vis[tx][ty]||!legal(tx,ty)||s[tx][ty]=='1') continue;
           vis[tx][ty]=1;
           q.push((node){tx,ty});
           if(tx+ty-1>res) {res=tx+ty-1;flag[res]=1;}
       }
   }
}

int main()
{
   int cas;
   scanf("%d",&cas);
   while(cas--)
   {
       scanf("%d %d",&n,&m);
       for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
       MM(flag,0);MM(vis,0);

       if(s[1][1]=='1')  {res=0;flag[1]=0;q.push((node){1,1});}
       else
       {
           res=1;
           flag[1]=1;
           bfs();
           if(res==n+m-1) {printf("0\n");continue;}
           for(int x=1;x<=n;x++)
             {
               int y=res+1-x;
               if(vis[x][y]) q.push((node){x,y});
             }
       }

       while(q.size())
       {
           int ux=q.front().x,uy=q.front().y;q.pop();
           if(flag[ux+uy-1]&&s[ux][uy]=='1') continue;
           for(int i=0;i<2;i++)
           {
               int vx=ux+dx[i],vy=uy+dy[i];
               if(!legal(vx,vy)||vis[vx][vy]) continue;
               vis[vx][vy]=1;
               if(s[vx][vy]=='1'&&!flag[vx+vy-1])  q.push((node){vx,vy});
               if(s[vx][vy]=='0') {flag[vx+vy-1]=1;q.push((node{vx,vy}));}
           }
       }

       int i=1;
       for(;i<=n+m-1;i++)
          if(!flag[i]) break;
       if(i>n+m-1) printf("0");
       else for(;i<=n+m-1;i++)
               printf("%d",!flag[i]);
       printf("\n");
   }
   return 0;
}

  分析:比赛时看到这道题过的人比较少,以为很难,,其实后来看了下题解,再自己想了下,发现自己比赛时离做出这道题

已经很近了,自己想到了,应该做矩阵的斜对角线,主要目标是在这个上面搜,然后也想到只能往右下角走,但是忘了一种特殊

情况,就是如果s[1][1]=='0'的话,那么就不一定非得往右下角走,但是总之得先通过0达到离点(n,m)最靠近的对角线,然后再往右下角走

 
 
posted @ 2016-07-16 18:45  快点说我帅  阅读(253)  评论(0编辑  收藏  举报