Walk Out
这题目的大致意思是一个人在n*m的迷宫里,一开始在(1,1)处,要走到(n,m)处,他每走一格都会记录下这格格子上的数,格子上不是1就是0,现在要使他记下来的这串二进制数最小。
考试的时候一直想着用dfs,然后一直爆内存,然后一直钻牛角尖,想着把数组开小点,因为就超了没多少内存,结果浪费了好长时间0.0
现在想想当时也是蠢,用bfs不就行了0.0
我的想法是
有这样一个迷宫
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
比如上述的例子中,先遍历0点
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
之后最后一步走到最后一格就完成了
0 | 0 | 1 |
1 | 1 | 1 |
1 | 0 | 1 |
所以说是101
代码附上,写的有点难看0.0
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
struct list{
public:
int x;
int y;
};
const int MAXN=1012;
char a[MAXN][MAXN];
list b[MAXN*MAXN];
bool p[MAXN][MAXN];
int i,j,num,n,m,l,r,p1,rr,pp;
list h;
void doit(int x,int y)//寻找下个可去点的
{
if (x+1<=n&&!p[x+1][y])
{
r++;
b[r].x=x+1;
b[r].y=y;
p[x+1][y]=1;
}
if (y+1<=m&&!p[x][y+1])
{
r++;
b[r].x=x;
b[r].y=y+1;
p[x][y+1]=1;
}
}
void sc(int x,int y)//用来遍历与(1,1)所有连着的0点
{
if (x>0&&x<=n&&y>0&&y<=m&&a[x][y]=='0'&&p[x][y]==0)
{
p[x][y]=1; r++;
b[r].x=x; b[r].y=y;
if (x+y>num) num=x+y;
}
}
int main()
{
int T;
string t1,t;
int i,l;
cin>>T;
for (int I=1;I<=T;I++)
{
pp=0;
memset(p,0,sizeof(p));
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++){ getchar();
for (j=1;j<=m;j++)
{
scanf("%c",&a[i][j]);
}
}
num=2; r=0;
if (a[1][1]=='0')
{
r=1; l=1; b[1].x=1; b[1].y=1; p[1][1]=1;
while (l<=r)
{
rr=r;
for (i=l;i<=rr;i++)
{
h=b[i];
sc(h.x+1,h.y);
sc(h.x-1,h.y);
sc(h.x,h.y-1);
sc(h.x,h.y+1);
}
l=rr+1;
}
r=0;
for (i=1;i<=n;i++)
if (num-i>0&&num-i<=m&&p[i][num-i]==1)
{
doit(i,num-i);
}
}
else { r=1; b[r].x=1; b[r].y=1; p[1][1]=1;}
l=1;
while (l<=r)
{
rr=r; p1=0;
for (i=l;i<=rr;i++)
if (a[b[i].x][b[i].y]=='0')//有0走0
{
doit(b[i].x,b[i].y);
p1=1;
}
if (p1==0)//没0 走1
{
cout<<1; pp=1;
for (i=l;i<=rr;i++)
{
doit(b[i].x,b[i].y);
}
} else cout<<0;
l=rr+1;
}
if (pp==0) cout<<0;
cout<<endl;
}
}