In an n∗mn∗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 (1≤n,m≤1000)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
题意:给出t组数据,每组数据给出一个n*m的图,图中每一个位置都有一个数字(0或1),每走到一个位置都会记录当前位置上的数字,要你求从左上角走到右下角中组成的最小的二进制数。
思路:当当前还没有1的时候,我们就可以先找出距离(距离=n+m-i-j+1)右下角最近的位置的0(位置可能不止一个)(到这个位置走的路上的数字都要求是0),然后我们就可以保证它的位数最小,为了保持位数
的最小,我们只能向右或向下走,每次走的时候,把这些位置都压入一个队列,然后进行bfs,每走到一个位置,我们都判断一下当前和这个位置到右下角距离相同的位置上是否有0,有零则非零的位置就可以不必往
后走了,用一个数组记录下每个位置都由那个方向走过来的,最后从右下角进行回溯记录答案就可以了。
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
char mp[1010][1010];
int mv[2][4]={1,0,0,-1,0,1,-1,0};
int vt[1010][1010];
int mt[1010][1010];
int vz[3030];
int lg;
int n,m;
char ans[1010];
struct st{
int x,y;
};
vector<st> v;
queue<st> q;
int check(int x,int y){
if(x<=n&&x>0&&y<=m&&y>0)
return 1;
return 0;
}
int bfs(){//找最近的1
int i,j;
st a,b;
memset(vt,0,sizeof(vt));//一定要记得清零
v.clear();//清空数组
a.x=1;
a.y=1;
int dis=1;
q.push(a);
vt[a.x][a.y]=1;
v.push_back(a);
int c;
while(!q.empty()){
a=q.front();
q.pop();
for(i=0;i<4;i++){
b.x=a.x+mv[0][i];
b.y=a.y+mv[1][i];
//printf("%d %d %d\n",mp[b.x][b.y]=='0',!vt[b.x][b.y],check(b.x,b.y));
if(mp[b.x][b.y]=='0'&&!vt[b.x][b.y]&&check(b.x,b.y)){
c=b.x+b.y-1;
//printf("b%d %d %d\n",b.x,b.y,c);
q.push(b);//把所有的可能的未标记的位置压入队列
if(c>dis){// 找到了新的最远距离
v.clear();//清空之前放入的位置
v.push_back(b);
dis=c;
}
else if(c==dis){
v.push_back(b); }
vt[b.x][b.y]=1;//标记
}
}
}
//printf("Q%d\n",dis);
return dis;//返回最远距离
}
/*3
5 6
001000
101010
101010
100010
111111
3 3
111
101
111
3 3
001
010
100
3 3
101
010
101*/
int bfs1(){
int i,j;
st a,b;
memset(vt,0,sizeof(vt));//一定要全部清零
memset(vz,0,sizeof(vz));
memset(mt,0,sizeof(mt));
vt[1][1]=1;
for(i=0;i<v.size()&&mp[1][1]=='0';i++){
q.push(v[i]);//放入找出的最远的位置
//printf("v%d %d\n",v[i].x,v[i].y);
vt[v[i].x][v[i].y]=1;
}
while(!q.empty()){
a=q.front();
//printf("a%d %d %d\n",a.x,a.y,vt[n][m]);
q.pop();
if(mp[a.x][a.y]=='1'&&vz[a.x+a.y-1])//如果和这个位置相同远的位置有0并且当前位置非零,这条路就一定不是最小的 ,就不必走下去了
continue;
for(i=0;i<2;i++){//向下和向右走
b.x=a.x+mv[0][i];
b.y=a.y+mv[1][i];
if(!vt[b.x][b.y]&&check(b.x,b.y)){
mt[b.x][b.y]=3-i;//记录该位置是由哪个方向走来的,便于回溯
//printf("b%d %d %d\n",b.x,b.y,3-i);
if(mp[b.x][b.y]=='0')//当前位置为0
vz[b.x+b.y-1]=1;
q.push(b);//放入队列
vt[b.x][b.y]=1;//标记
}
}
}
}
int main(){
int t;
int i,j;
int lg=0,cnt;
scanf("%d",&t);
while(t--){
lg=0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
getchar();
scanf("%s",mp[i]+1);
}
lg=0;
st a;
a.x=1;
a.y=1;
if(mp[1][1]=='0'&&bfs()==(n+m-1)){//看是否有一条全为0的路
printf("0\n");
lg=1;
}
else if(!lg){
if(mp[1][1]=='1'){
q.push(a);
v.clear();//清空上一组数据的最远位置
}
bfs1();
int x,y,t;
x=n,y=m;
t=mt[x][y];//回溯方向
//printf("t%d\n",t);
cnt=0;
while(t>1){
ans[cnt++]=mp[x][y];
x+=mv[0][t];
y+=mv[1][t];
t=mt[x][y];
}
while(ans[cnt-1]=='0'&&cnt>1&&mp[1][1]=='0')//清除前缀零
cnt--;
if(mp[1][1]=='1')//第一个位置没有来自的位置
printf("1");
for(i=cnt-1;i>=0;i--)//逆向输出答案
printf("%c",ans[i]);
printf("\n");
}
}
return 0;
}

  

hdu5335(bfs,贪心)的更多相关文章

  1. UVA12130 Summits(BFS + 贪心)

    UVA12130 Summits(BFS + 贪心) 题目链接 题目大意: 给你一个h ∗ w 的矩阵,矩阵的每一个元素都有一个值,代表这个位置的高度. 题目要求你找出这个图中有多少个位置是峰值点.从 ...

  2. BFS+贪心 HDOJ 5335 Walk Out

    题目传送门 /* 题意:求从(1, 1)走到(n, m)的二进制路径值最小 BFS+贪心:按照标程的作法,首先BFS搜索所有相邻0的位置,直到1出现.接下去从最靠近终点的1开始, 每一次走一步,不走回 ...

  3. HDU-1072 Nightmare (bfs+贪心)

    Nightmare Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Sub ...

  4. noip2010 引水入城 bfs+贪心

    如果能够实现,每个河边的城市对应的控制区域一定是一条线段. 所以直接bfs每个河边的城市,贪心线段的右端点 #include<cstdio> #include<cstring> ...

  5. G、CSL 的训练计划【BFS 贪心】(“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)

    题目传送门:https://ac.nowcoder.com/acm/contest/551/G 链接:https://ac.nowcoder.com/acm/contest/551/G来源:牛客网 题 ...

  6. luogu 1066 引水入城(bfs+贪心)

    90分,有一个点TLE.... 首先可以证明一个东西,如果从上面一排的某个点bfs一次到最下面一排的饮水点不是一个区间的话,那么最后一定所有饮水点不会被覆盖完的. 证明考虑反证法. 所以从上面一排的每 ...

  7. vijos p1777 引水入城(bfs+贪心)

    引水入城   描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,其中每个格子都代表一座城市,每座城市都有一个海拔高度. 为了使 ...

  8. UVA 12130 - Summits(BFS+贪心)

    UVA 12130 - Summits 题目链接 题意:给定一个h * w的图,每一个位置有一个值.如今要求出这个图上的峰顶有多少个.峰顶是这样定义的.有一个d值,假设一个位置是峰顶.那么它不能走到不 ...

  9. NOIP2010_T4_引水入城 bfs+贪心

    在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 N 行 M 列的矩形,如上图所示,其中每个格子都代表一座城 市,每座城市都有一个海拔高度.为了使 ...

  10. luoguP1514 引水入城 题解(NOIP2010)(Bfs+贪心)

    P1514 引水入城  题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<c ...

随机推荐

  1. linux文件管理之bash shell

    BASH Shell 对文件进行管理 ========================================================创建.复制.删除.移动.查看.编辑.压缩.查找 内 ...

  2. 20170706xlVBA批量提取word表格中的自我评分

    单位里普遍存在各种低效率的办公行为,比如每年的自我评分.评分细目表为word文档,每行一个项目,每个项目要填写得分事项和分值,组长审核之后转成Excel向上递交.主要涉及到问题就是word文档中一列得 ...

  3. 『TensorFlow』第十一弹_队列&多线程&TFRecod文件_我辈当高歌

    TF数据读取队列机制详解 一.TFR文件多线程队列读写操作 TFRecod文件写入操作 import tensorflow as tf def _int64_feature(value): # val ...

  4. hdu 1025LIS思路同1257 二分求LIS

    题目: Constructing Roads In JGShining's Kingdom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit ...

  5. LINQ 中常用函数使用: Take TakeWhile Skip SkipWhile Reverse Distinct

    1,Take 方法 Take方法用于从一个序列的开头返回指定数量的元素. string[] names = { "郭靖", "李莫愁", "欧阳晓晓& ...

  6. 用swoole简单实现MySQL连接池

    MySQL连接池 在传统的网站开发中,比如LNMP模式,由Nginx的master进程接收请求然后分给多个worker进程,每个worker进程再链接php-fpm的master进程,php-fpm再 ...

  7. 数据结构与算法之PHP查找算法(顺序查找)

    对于查找数据来说,最简单的方法就是从列表的第一个元素开始对列表元素逐个进行判断,直到找到了想要的结果,或者直到列表结尾也没有找到,这种方法称为顺序查找. 一.基本写法 顺序查找的实现很简单.只要从列表 ...

  8. 几种常见的开源软件许可协议(GPL, LGPL, Apache License, BSD)

    GPL GPL授予程序接受人以下权利,或称“自由”: * 以任何目的运行此程序的自由 * 以学习程序工作机理为目的,对程序进行修改的自由(能得到源代码是前提) * 再发行复制件的自由 * 改进此程序, ...

  9. Spring注解之 @SuppressWarnings注解

    简介:java.lang.SuppressWarnings是J2SE5.0中标准的Annotation之一.可以标注在类.字段.方法.参数.构造方法,以及局部变量上.作用:告诉编译器忽略指定的警告,不 ...

  10. Git:合并分支冲突问题

    首先创建分支feature1,并且修改readme.txt内容,再在该分支上提交. 切换回master分支, 并且修改readme.txt内容,再在master分支上提交. 此时的分支路线如下,合并时 ...