代码写的搓,结果爆栈了,加个扩栈的就好了,整体思路就是按向下、向右的法则走,因为终点在右下角,这样走能确保二进制长度最短,然后考虑下前导零的情况,我们可以先用dfs预处理下零点的情况,把离终点近的点插到优先队列里,写的比较暴力,还在服务器6,没TLE。
#pragma comment(linker, "/STACK:102400000,102400000") //C++
int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p)); //G++ 貌似杭电编译不过
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <queue>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
char mp[1005][1005];
int n, m;
bool vis[1005][1005], v[1005][1005];
struct point
{
string ans;
int x, y;
friend bool operator < (point a,point b)
{
return a.ans>b.ans;
}
};
int dirx[] = {0, 1};
int diry[] = {1, 0};
int dirxx[] = {0, 1, -1, 0};
int diryy[] = {1, 0, 0, -1};
bool judge(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y]);
}
bool Judge(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m && !v[x][y]);
}
priority_queue <point> q;
point ok;
bool isok(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m);
}
bool flag = false;
vector <point> Q;int minn=5000;
void dfs(int x, int y)
{
if(x == n - 1 && y == m - 1)flag = true;
bool f = false;
for(int i = 0; i < 4; ++i)
{
int nx = x + dirxx[i];
int ny = y + diryy[i];
if(judge(nx, ny))
{
if(mp[nx][ny] == '0')
{
f = true;
vis[nx][ny] = true;
dfs(nx, ny);
}
}
}
if(!f)
{
for(int i = 0; i < 2; ++i)
{
int xx = x + dirx[i], yy = y + diry[i];
if(isok(xx, yy))
{
if(mp[xx][yy]=='0')continue;
ok.x = xx;
ok.y = yy;
if(v[xx][yy])continue;
ok.ans = "1";
minn=min(minn,abs(xx-n)+abs(yy-m));
Q.push_back(ok);
v[xx][yy] = true;
}
}
}
}
string bfs()
{
point F, N;
bool f;
while(!q.empty())
{
F = q.top();
q.pop();
f = true;
if(F.x == n-1 && F.y == m-1)return F.ans;
for(int i = 0; i < 2; ++i)
{
N.x = F.x + dirx[i];
N.y = F.y + diry[i];
if(Judge(N.x, N.y))
if(mp[N.x][N.y] == '0')
{
f = false;
N.ans = F.ans + '0';
q.push(N);
v[N.x][N.y] = true;
}
}
if(f)
{
for(int i = 0; i < 2; ++i)
{
N.x = F.x + dirx[i];
N.y = F.y + diry[i];
if(Judge(N.x, N.y))
{
N.ans = F.ans + '1';
q.push(N);
v[N.x][N.y] = true;
}
}
}
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
getchar();Q.clear();minn=5000;
for(int i = 0; i < n; ++i)
{
scanf("%s", &mp[i]);
}
while(!q.empty())q.pop();
flag = false;
memset(vis, false, sizeof(vis));
memset(v, false, sizeof(v));
if(mp[0][0] == '0')
{
dfs(0, 0);
int len=Q.size();
for(int i=0;i<len;++i)
{
if(abs(Q[i].x-n)+abs(Q[i].y-m)==minn)
{
q.push(Q[i]);
}
}
}
else
{
ok.ans = "1";
ok.x = 0;
ok.y = 0;
q.push(ok);
}
memset(v, false, sizeof(v));v[0][0]=true;
if(flag)
{
puts("0");
continue;
}
string x = bfs();
int i, len = x.length();
for(i = 0; i < len; ++i)
{
if(x[i] != '0')break;
}
if(i == len)puts("0");
else
{
for(; i < len; ++i)putchar(x[i]);
puts("");
}
}
return 0;
}