题意:有一个n*m的矩阵,每个格子中有一个数字,或为0,或为1。有个人要从(1,1)到达(n,m),要求所走过的格子中的数字按先后顺序串起来后,用二进制的判断大小方法,让这个数字最小。前缀0不需要输出!!

思路:主要考虑的是BFS解决。

  如果grid[1,1]=1,那么这个二进制的位数也就定下来了,是n+m-1,很好解决,每个格子就只能往下或者往右,否则长度一定超过n+m+1,必定不是最优。

  如果grid[1,1]=0,那么可能会出现绕了一个S型到终点的结果为0而已。所以不能用老办法,要先预处理一下。处理方式是,用BFS将所有grid[1,1]可达的0点标记出来,找出其中距离终点最近的那些0点(可能多个),如果他们的下和右边的点为1,这些点都进队,再用上边方式BFS即可求得答案(上面只是1个起点,这边有多个起点,不影响正确性)。

  答案在哪?其实在BFS时每一层只能是0点或者是1点,为什么呢?如果有0点的话,还需要选择1点的吗?别忘了二进制的位数是固定了,选0肯定比选1要好,则在没有0的情况下再选1的。 在遍历时按层遍历,遍历到的点先分到两个集合A0和B1中,择所需即可,所以在遍历第i层时第i位的答案也就决定了。这是剪枝!

  注意考虑只有1个点,2个点和S形等各种情况。

 #include <bits/stdc++.h>
#define INF 0x7f7f7f7f
#define pii pair<int,int>
#define LL unsigned long long
using namespace std;
const int N=;
int n, m;
char grid[N][N];
vector<int> ans;
int inq[N][N]; void BFS(deque<pii> &que)
{
ans.push_back();
while(!que.empty())
{
deque<pii> que0, que1; //两种到达的方式,只取其一
int siz=que.size();
for(int i=; i<siz; i++) //被更新的都是同一源头的。
{
int a=que.front().first;
int b=que.front().second;
que.pop_front(); if( a+<=n && !inq[a+][b] ) //下:要么你无路径可达,要么我比你小,我才更新你
{
if(grid[a+][b]=='') que0.push_back(make_pair(a+,b));
else que1.push_back(make_pair(a+,b));
}
if( b+<=m && !inq[a][b+] ) //右
{
if(grid[a][b+]=='') que0.push_back(make_pair(a,b+));
else que1.push_back(make_pair(a,b+));
}
inq[a+][b]=inq[a][b+]=;
} if(!que0.empty()) ans.push_back();
else ans.push_back(); if(!que0.empty()) que.insert(que.end(), que0.begin(), que0.end() );
else que.insert(que.end(), que1.begin(), que1.end() );
}
} int cal()
{
memset(inq, , sizeof(inq)); deque<pii> que;que.push_back( make_pair(,));
if(grid[][]=='') //若起点为0,找到所有离终点最近的前缀0
{
inq[][]=;
while(!que.empty())
{
int siz=que.size();
for(int i=; i<siz; i++) //按层来BFS,按层记录最优答案
{
int a=que.front().first;
int b=que.front().second;
que.pop_front(); if(a+<=n && !inq[a+][b] && grid[a+][b]=='') que.push_back(make_pair(a+,b));
if(a-> && !inq[a-][b] && grid[a-][b]=='') que.push_back(make_pair(a-,b)); if(b+<=m && !inq[a][b+] && grid[a][b+]=='') que.push_back(make_pair(a,b+));
if(b-> && !inq[a][b-] && grid[a][b-]=='') que.push_back(make_pair(a,b-)); inq[a+][b]=inq[a-][b]=inq[a][b+]=inq[a][b-]=; //防止重复进队
}
}
int min_dis=INF;
for(int i=; i<=n; i++) //求最近的0距离终点的最小距离
{
for(int j=; j<=m; j++)
{
if(inq[i][j]&&grid[i][j]=='')
min_dis=min(min_dis, n+m-j-i);
}
}
if(grid[n][m]=='' && min_dis==) return ; //有0路可达终点
for(int i=; i<=n; i++) //扫出距离为min_dis的所有0点
for(int j=; j<=m; j++)
if(inq[i][j] && grid[i][j]=='' && min_dis==n+m-j-i && n+m-i-j!= )
que.push_back(make_pair(i,j)); memset(inq,,sizeof(inq));
int siz=que.size();
for(int i=; i<siz; i++) //将所有0点的下和右为1的点进队
{
int a=que.front().first;
int b=que.front().second;
que.pop_front();
if(a+<=n&&!inq[a+][b]&&grid[a+][b]=='') que.push_back(make_pair(a+,b));
if(b+<=m&&!inq[a][b+]&&grid[a][b+]=='') que.push_back(make_pair(a,b+));
inq[a+][b]=inq[a][b+]=;
}
}
BFS(que);
return ans.size();
} int main()
{
freopen("input.txt", "r", stdin);
int t, a, b;
char c;
cin>>t;
while(t--)
{
ans.clear();
scanf("%d %d",&n,&m); for(int i=; i<=n; i++) //输入要注意
for(int j=; j<=m; j++)
{
c=getchar();
if(c==''||c=='' ) grid[i][j]=c;
else j--;
}
int s=cal();
if(s==) printf("");
else for(int i=; i+<ans.size(); i++) printf("%d",ans[i]);//最后一个数字多余
printf("\n");
}
return ;
}

AC代码

HDU 5335 Walk Out (BFS,技巧)的更多相关文章

  1. HDU 5335 Walk Out BFS 比较坑

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

  2. hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4

    题意—— 一个n*m的地图,从左上角走到右下角. 这个地图是一个01串,要求我们行走的路径形成的01串最小. 注意,串中最左端的0全部可以忽略,除非是一个0串,此时输出0. 例: 3 3 001 11 ...

  3. hdu 5335 Walk Out(bfs+寻找路径)

    Problem Description In an n∗m maze, the right-bottom corner or a written on it. An explorer gets los ...

  4. hdu 5335 Walk Out (搜索)

    题目链接: hdu 5335 Walk Out 题目描述: 有一个n*m由0 or 1组成的矩形,探险家要从(1,1)走到(n, m),可以向上下左右四个方向走,但是探险家就是不走寻常路,他想让他所走 ...

  5. HDU 5335——Walk Out——————【贪心】

    Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  6. HDU 5335 Walk Out(多校)

    Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  7. hdu 5335 Walk Out (2015 Multi-University Training Contest 4)

    Walk Out                                                                         Time Limit: 2000/10 ...

  8. hdu 5335 Walk Out 搜索+贪心

    Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total S ...

  9. 2015 Multi-University Training Contest 4 hdu 5335 Walk Out

    Walk Out Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

随机推荐

  1. 分布式数据存储 - Zabbix监控MySQL性能

    Zabbix如何监控mysql性能,我们可以使用mysql自带的模板,可以监控如下内容:OPS(增删改查).mysql请求流量带宽,mysql响应流量带宽,最后会附上相应的监控图! 编写check_m ...

  2. Java日志记录的事儿

    一.java日志组件 1.common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的 ...

  3. HDU 1385 Minimum Transport Cost (Dijstra 最短路)

    Minimum Transport Cost http://acm.hdu.edu.cn/showproblem.php?pid=1385 Problem Description These are ...

  4. 2014多校第三场1005 || HDU 4891 The Great Pan(模拟)

    题目链接 题意 : 给你n行字符串,问你有多少种理解方式.有两大类的理解 (1){A|B|C|D|...}代表着理解方式可以是A,可以是B或C或者D. (2)$blah blah$,在$$这两个符号中 ...

  5. sql 泡沫 或者 递归查询

    if object_id('[tb]') is not null drop table [tb] go ),parentid int) insert [tb] ,N union all ,N unio ...

  6. Linux command: usermod -- 改变用户状态

    应用举例: 1. usermod -g newuser newuser force use GROUP as new primary group. 一般时候是默认的,也是必须的(不能更改).2. 指定 ...

  7. Things about single men that women hate

    Things about single men that women hate为何你俘获不了女神的心?If you listen in to a group of single women talki ...

  8. 根据ip查询地区,经纬度等-geoip2

    这项工作难度主要在数据上,数据越准确越有利. 1. 下载数据文件: http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.m ...

  9. sin=in.readLine();

    import java.io.*; public class LineIO{ public static void main(String[] args) { String sin,inputStri ...

  10. sublime3 乱码问题

    解决方法: 一.安装Package Control 二.按Ctrl+Shift+P打开命令行,输入Install Package,回车,然后继续输入ConvertToUTF8,回车  (把GB2312 ...