标签:
http://acm.hdu.edu.cn/showproblem.php?pid=5335
2 2 2 11 11 3 3 001 111 101
111 101
/**
hdu5335 多校联合第四场1009 搜索
题目大意:给定一个由0和1组成的棋盘,从左上角走到右下角路径(上下左右四种行走方式)组成二进制数问最小的是什么
解题思路:(转)如果我们规定这个人只能向下走或者向右走的话,问题会变的简单,二进制长度为n-m+1,然后我们可以一步一步求它每一步走的情况。
首先他的二进制第一位一定要为0。在第一位为0之后一定只会向下或者向右走到终点,因为中间如果向上走或者向左走的话,二进制的
位数会增加,大小肯定增大,所以问题的关键是找出从原点一直走0的位置,中间经过的0的位置距离终点最短的点,在这之后便只能向
下走或者向右走。
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int maxn=1003;
int n,m,ans;
bool flag[maxn][maxn];
char a[maxn][maxn];
int dx[][2]= {1,0,0,1,-1,0,0,-1};
void bfs()
{
queue <pair<int,int> >q;
memset(flag,0,sizeof(flag));
q.push(make_pair(0,0));
while(!q.empty())
{
int x=q.front().first;
int y=q.front().second;
q.pop();
for(int i=0; i<4; i++)
{
int xx=x+dx[i][0];
int yy=y+dx[i][1];
if(flag[xx][yy]||xx<0||xx>=n||yy<0||yy>=m)continue;
flag[xx][yy]=1;
ans=max(xx+yy,ans);
if(a[xx][yy]=='0') q.push(make_pair(xx,yy));
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++)
{
scanf("%s",a[i]);
}
ans=0;
flag[0][0]=1;
if(a[0][0]=='0')bfs();
if(ans==n+m-2)
{
printf("%c\n",a[n-1][m-1]);
continue;
}
printf("1");
bool ok=0;
for(int i=ans; i<n-1+m-1; i++)
{
bool judge=0;
for(int k=0; k<=i; k++)
{
int x=k;
int y=i-k;
if(x<0||x>=n||y<0||y>=m||flag[x][y]==0)continue;
if(ok&&a[x][y]=='1')continue;
for(int j=0; j<2; j++)
{
int xx=x+dx[j][0];
int yy=y+dx[j][1];
if(xx<0||xx>=n||yy<0||yy>=m)continue;
flag[xx][yy]=1;
if(a[xx][yy]=='0')judge=1;
}
}
ok=judge;
if(judge)printf("0");
else printf("1");
}
printf("\n");
}
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/47169487