HDU 5335 Walk Out(多校)
Walk Out
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.
For each testcase, the first line contains two integers n and m (1≤n,m≤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.
2 2
11
11
3 3
001
111
101
101
本题思路:
1.先判断第一个点是不是0,如果是0先把所有的0都走一遍,找到哈曼顿距离最小的点(可能会有几个)。
这个过程可以用DFS也可以BFS(建议BFS,因为DFS会爆栈,必须自己把栈开导最大,后面会说明)
2.如果第一点不是0,直接从第一个点开始搜,只搜下和右两个方向,如果这两个方向有两个0,输出0,把两个0都加入队列;如果只有一个0,输出0,只把0那个点加入队列;如果是两个1,也把两个点都加入队列。
3.如果第一个点是0,再把这个0的右边的点和下边的点(超边界的不算)都加入队列开始用2的方法搜。
开始用DFS搜
#pragma comment(linker, "/STACK:10240000000000,10240000000000")//这行代码不加就会STACK_OVERFLOW
#include<queue>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1234
struct point
{
int x,y,d;
}st[N*]; int dx[]={,,-,};
int dy[]={,,,-};
int n,m,k,dis,flag;
char mat[N][N];
bool vis[N][N]; void dfs(int x,int y)
{
if(x<||x>n||y<||y>m)return;
if(mat[x][y]=='')return;
if(vis[x][y]==)return;
vis[x][y]=;
if(dis<x+y)
{
k=;
dis=x+y;
st[k].x=x;
st[k++].y=y;
}
else if(dis==x+y)
{
st[k].x=x;
st[k++].y=y;
}
for(int i=;i<;i++)
dfs(x+dx[i],y+dy[i]);
}
void bfs()
{
memset(vis,,sizeof(vis));
queue<point>q1;
queue<point>q2;
for(int i=;i<k;i++)
{
if(mat[st[i].x][st[i].y]=='')
{
if(st[i].x==n&&st[i].y==m){printf("");return;}
point a1=st[i],a2=st[i];
a1.x++;a2.y++;
if(a1.x<=n)
q1.push(a1),vis[a1.x][a1.y]=;
if(a2.y<=m)
q1.push(a2),vis[a2.x][a2.y]=;
}
else
q1.push(st[i]),vis[st[i].x][st[i].y]=;
}
printf("");
if(vis[n][m])return;
while()
{
flag=;
while(!q1.empty())
{
point cur=q1.front();
q1.pop();
for(int i=;i<;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(vis[next.x][next.y] || next.x< || next.x>n || next.y< || next.y>m)continue;
if(mat[next.x][next.y] == '')
flag = ;
q2.push(next);
vis[next.x][next.y]=;
}
}
printf("%d",flag);
if(vis[n][m])return; while(!q2.empty())
{
point cur=q2.front();
q2.pop();
if(flag==)
q1.push(cur);
else if(flag== && mat[cur.x][cur.y]=='')
q1.push(cur);
}
}
} int main()
{
int t;cin>>t;
while(t--)
{
memset(vis,,sizeof(vis));
dis=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%s",mat[i]+); if(mat[][]=='')
st[].x=,st[].y=,k=;
else
dfs(,);
bfs();
cout<<endl;
}
return ;
} //几组比较好的数据 /*
5
2 2
01
11
2 2
00
11
2 2
00
00
3 3
000
110
110
3 3
000
110
111 */
开始用BFS搜(推荐)
#include<queue>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1234
struct point
{
int x,y;
}st[N*];
int dx[]={,,-,};
int dy[]={,,,-};
int n,m,k,dis;
char mat[N][N];
bool vis[N][N]; void bfs1()
{
memset(vis,,sizeof(vis));
queue<point>q;
point first;
first.x=first.y=;
q.push(first);vis[][]=;
st[].x=st[].y=;
k=;
while(!q.empty())
{
point cur=q.front();
q.pop();
for(int i=;i<;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(next.x<||next.x>n||next.y<||next.y>m)continue;
if(vis[next.x][next.y] || mat[next.x][next.y]=='')continue;
q.push(next);vis[next.x][next.y]=;
if(dis<next.x+next.y)
{
k=;
dis=next.x+next.y;
st[k].x=next.x;
st[k++].y=next.y;
}
else if(dis==next.x+next.y)
{
st[k].x=next.x;
st[k++].y=next.y;
}
}
}
}
void bfs()
{
memset(vis,,sizeof(vis));
queue<point>q1;
queue<point>q2;
for(int i=;i<k;i++)
{
if(mat[st[i].x][st[i].y]=='')
{
if(st[i].x==n&&st[i].y==m){printf("");return;}
point a1=st[i],a2=st[i];
a1.x++;a2.y++;
if(a1.x<=n)
q1.push(a1),vis[a1.x][a1.y]=;
if(a2.y<=m)
q1.push(a2),vis[a2.x][a2.y]=;
}
else
q1.push(st[i]),vis[st[i].x][st[i].y]=;
}
printf("");
if(vis[n][m])return;
while()
{
int flag=;
while(!q1.empty())
{
point cur=q1.front();
q1.pop();
for(int i=;i<;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(vis[next.x][next.y] || next.x< || next.x>n || next.y< || next.y>m)continue;
if(mat[next.x][next.y] == '')
flag = ;
q2.push(next);
vis[next.x][next.y]=;
}
}
printf("%d",flag);
if(vis[n][m])return; while(!q2.empty())
{
point cur=q2.front();
q2.pop();
if(flag==)
q1.push(cur);
else if(flag== && mat[cur.x][cur.y]=='')
q1.push(cur);
}
}
} int main()
{
int t;cin>>t;
while(t--)
{
dis=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%s",mat[i]+); if(mat[][]=='')
st[].x=,st[].y=,k=;
else
bfs1();
bfs();
cout<<endl;
}
return ;
}
其他:
1输图的时候不要%c输入,用%s输入,速度会快很多,这题如果用%c输入会TLE,(花了一下午时间找为什么TLE,最后发现居然是因为输图方式。) 所以以后都要用:
for(int i=;i<n;i++)
scanf("%s",mat[i];
or
for(int i=;i<=n;i++)
scanf("%s",mat[i]+);
2 dfs是很容易爆栈的,这题就是我开始写的用dfs的就爆栈了,这时候有一个处理办法:在代码最前面加:#pragma comment(linker, "/STACK:10240000000000,10240000000000") 这句意思是自己开一个非常大的栈,STACK:后面那数字好像已经是能开的最大的了。
此题中加入这一行本来的Runtime Error(STACK_OVERFLOW)就会变成 Accepted!
但是好像正规比赛不允许使用这种方式。
HDU 5335 Walk Out(多校)的更多相关文章
- hdu 5335 Walk Out (搜索)
题目链接: hdu 5335 Walk Out 题目描述: 有一个n*m由0 or 1组成的矩形,探险家要从(1,1)走到(n, m),可以向上下左右四个方向走,但是探险家就是不走寻常路,他想让他所走 ...
- HDU 5335 Walk Out BFS 比较坑
H - H Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Submit Status ...
- HDU 5335——Walk Out——————【贪心】
Walk Out Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- hdu 5335 Walk Out (2015 Multi-University Training Contest 4)
Walk Out Time Limit: 2000/10 ...
- hdu 5335 Walk Out 搜索+贪心
Walk Out Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total S ...
- 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 ...
- HDU 5335 Walk Out (BFS,技巧)
题意:有一个n*m的矩阵,每个格子中有一个数字,或为0,或为1.有个人要从(1,1)到达(n,m),要求所走过的格子中的数字按先后顺序串起来后,用二进制的判断大小方法,让这个数字最小.前缀0不需要输出 ...
- hdu 5335 Walk Out(bfs+斜行递推) 2015 Multi-University Training Contest 4
题意—— 一个n*m的地图,从左上角走到右下角. 这个地图是一个01串,要求我们行走的路径形成的01串最小. 注意,串中最左端的0全部可以忽略,除非是一个0串,此时输出0. 例: 3 3 001 11 ...
- HDU 5335 Walk Out
题意:在一个只有0和1的矩阵里,从左上角走到右下角, 每次可以向四个方向走,每个路径都是一个二进制数,求所有路径中最小的二进制数. 解法:先bfs求从起点能走到离终点最近的0,那么从这个点起只向下或向 ...
随机推荐
- 彻底理解Python中的yield
阅读别人的python源码时碰到了这个yield这个关键字,各种搜索终于搞懂了,在此做一下总结: 通常的for…in…循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文 ...
- 10大vim插件
Taglist taglist是一个用于显示定位程序中各种符号的插件,例如宏定义.变量名.结构名.函数名这些东西 我们将其称之为符号(symbols),而在taglist中将其称之为tag.显然,要想 ...
- vim 第三章 插入模式
vim 第三章 插入模式 在普通模式下可以删除 复制 及粘贴的命令 在插入模式下也存在以中方便快捷的方式 能够粘贴寄存器中文本 两种方式来插入键盘上不存在的非常用字符 替换模式 ...
- 【JavaScript 14—学习总结】:从小事做起
导读:花了将近两个月,JavaScript的学习视频算是做完了.里面的例子,都敲过一遍,但有少数的几个就是实现不了,比如:百度分享侧栏随着滚动条移动:菜单切换只对第一个起作用等,也就先放着了.现在,就 ...
- HDU-4612 Warm up,tarjan求桥缩点再求树的直径!注意重边
Warm up 虽然网上题解这么多,感觉写下来并不是跟别人竞争访问量的,而是证明自己从前努力过,以后回头复习参考! 题意:n个点由m条无向边连接,求加一条边后桥的最少数量. 思路:如标题,tarjan ...
- Android隐藏软键盘收回软键盘
代码改变世界 Android隐藏软键盘收回软键盘 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPU ...
- 【Luogu】P2051中国象棋(DP)
题目链接 去看STDCALL的题解吧 #include<cstdio> #include<cctype> #define mod 9999973 inline long lon ...
- HDU4405-Aeroplane chess(概率DP求期望)
Hzz loves aeroplane chess very much. The chess map contains N+1 grids labeled from 0 to N. Hzz start ...
- 洛谷 [P2953] 牛的数字游戏
SG搜索 n的范围在可以接受的范围内,SG搜索即可 #include <iostream> #include <cstdio> #include <cstring> ...
- DP的序--Codeforces626F. Group Projects
$n \leq 200$个数,$ \leq 500$,$K \leq 1000$代价内的数字分组有多少?一个分组的代价是分成的每个小组的总代价:一个小组的代价是极差. 问的极差那就从极入手嘛.一个小组 ...