您的位置:首页 > 其它

HDU 5335 Walk Out(多校)

2015-08-03 17:06 399 查看

Walk Out

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2912 Accepted Submission(s): 599




[align=left]Problem Description[/align]


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.


[align=left]Input[/align]


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


[align=left]Output[/align]


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


[align=left]Sample Input[/align]


2
2 2
11
11
3 3
001
111
101



[align=left]Sample Output[/align]


111
101



[align=left]Author[/align]


XJZX


[align=left]Source[/align]


2015 Multi-University Training Contest 4


[align=left]Recommend[/align]


wange2014 | We have carefully selected several similar problems for you: 5342 5341 5340 5339 5338


本题思路:

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*2];

int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int n,m,k,dis,flag;
char mat

;
bool vis

;

void dfs(int x,int y)
{
if(x<1||x>n||y<1||y>m)return;
if(mat[x][y]=='1')return;
if(vis[x][y]==1)return;
vis[x][y]=1;
if(dis<x+y)
{
k=0;
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=0;i<4;i++)
dfs(x+dx[i],y+dy[i]);
}
void bfs()
{
memset(vis,0,sizeof(vis));
queue<point>q1;
queue<point>q2;
for(int i=0;i<k;i++)
{
if(mat[st[i].x][st[i].y]=='0')
{
if(st[i].x==n&&st[i].y==m){printf("0");return;}
point a1=st[i],a2=st[i];
a1.x++;a2.y++;
if(a1.x<=n)
q1.push(a1),vis[a1.x][a1.y]=1;
if(a2.y<=m)
q1.push(a2),vis[a2.x][a2.y]=1;
}
else
q1.push(st[i]),vis[st[i].x][st[i].y]=1;
}
printf("1");
if(vis
[m])return;
while(1)
{
flag=1;
while(!q1.empty())
{
point cur=q1.front();
q1.pop();
for(int i=0;i<2;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(vis[next.x][next.y] || next.x<1 || next.x>n || next.y<1 || next.y>m)continue;
if(mat[next.x][next.y] == '0')
flag = 0;
q2.push(next);
vis[next.x][next.y]=1;
}
}
printf("%d",flag);
if(vis
[m])return;

while(!q2.empty())
{
point cur=q2.front();
q2.pop();
if(flag==1)
q1.push(cur);
else if(flag==0 && mat[cur.x][cur.y]=='0')
q1.push(cur);
}
}
}

int main()
{
int t;cin>>t;
while(t--)
{
memset(vis,0,sizeof(vis));
dis=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",mat[i]+1);

if(mat[1][1]=='1')
st[0].x=1,st[0].y=1,k=1;
else
dfs(1,1);
bfs();
cout<<endl;
}
return 0;
}

//几组比较好的数据

/*
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*2];
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
int n,m,k,dis;
char mat

;
bool vis

;

void bfs1()
{
memset(vis,0,sizeof(vis));
queue<point>q;
point first;
first.x=first.y=1;
q.push(first);vis[1][1]=1;
st[0].x=st[0].y=1;
k=1;
while(!q.empty())
{
point cur=q.front();
q.pop();
for(int i=0;i<4;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(next.x<1||next.x>n||next.y<1||next.y>m)continue;
if(vis[next.x][next.y] || mat[next.x][next.y]=='1')continue;
q.push(next);vis[next.x][next.y]=1;
if(dis<next.x+next.y)
{
k=0;
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,0,sizeof(vis));
queue<point>q1;
queue<point>q2;
for(int i=0;i<k;i++)
{
if(mat[st[i].x][st[i].y]=='0')
{
if(st[i].x==n&&st[i].y==m){printf("0");return;}
point a1=st[i],a2=st[i];
a1.x++;a2.y++;
if(a1.x<=n)
q1.push(a1),vis[a1.x][a1.y]=1;
if(a2.y<=m)
q1.push(a2),vis[a2.x][a2.y]=1;
}
else
q1.push(st[i]),vis[st[i].x][st[i].y]=1;
}
printf("1");
if(vis
[m])return;
while(1)
{
int flag=1;
while(!q1.empty())
{
point cur=q1.front();
q1.pop();
for(int i=0;i<2;i++)
{
point next=cur;
next.x+=dx[i],next.y+=dy[i];
if(vis[next.x][next.y] || next.x<1 || next.x>n || next.y<1 || next.y>m)continue;
if(mat[next.x][next.y] == '0')
flag = 0;
q2.push(next);
vis[next.x][next.y]=1;
}
}
printf("%d",flag);
if(vis
[m])return;

while(!q2.empty())
{
point cur=q2.front();
q2.pop();
if(flag==1)
q1.push(cur);
else if(flag==0 && mat[cur.x][cur.y]=='0')
q1.push(cur);
}
}
}

int main()
{
int t;cin>>t;
while(t--)
{
dis=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%s",mat[i]+1);

if(mat[1][1]=='1')
st[0].x=1,st[0].y=1,k=1;
else
bfs1();
bfs();
cout<<endl;
}
return 0;
}


其他:

1输图的时候不要%c输入,用%s输入,速度会快很多,这题如果用%c输入会TLE,(花了一下午时间找为什么TLE,最后发现居然是因为输图方式。) 所以以后都要用:

for(int i=0;i<n;i++)
scanf("%s",mat[i];
or
for(int i=1;i<=n;i++)
scanf("%s",mat[i]+1);


2 dfs是很容易爆栈的,这题就是我开始写的用dfs的就爆栈了,这时候有一个处理办法:在代码最前面加:#pragma comment(linker, "/STACK:10240000000000,10240000000000") 这句意思是自己开一个非常大的栈,STACK:后面那数字好像已经是能开的最大的了。
此题中加入这一行本来的Runtime Error(STACK_OVERFLOW)就会变成 Accepted!

但是好像正规比赛不允许使用这种方式。

      
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: