题意:
求从坐标 (1,1) 到 (n,n) 的路径中,所能得到的二进制数最小是什么。
解析:
要分情况讨论。
1. 如果 (1,1) 是 1 的情况,那么这种情况用bfs求出字典序最小的二进制数。
2. 如果(1,1) 是 0 那么就沿着0走,搜索出所有最远可达点,然后把这些点Push进队列中,并进行bfs求出字典序最小的二进制数。
对于bfs可以开一个zero数组来记录,到这步是否存在0。如果走到这步,存在0,且当前这要走的是1,就continue,剪枝。
最后把zero数组输出就好了。
注意:
dfs可能会爆栈,所以要用汇编扩栈。
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1005;
const int dx[] = {1, 0, -1, 0};
const int dy[] = { 0, 1, 0, -1};
struct Node {
int x, y, step;
Node() {}
Node(int x, int y, int step)
: x(x), y(y), step(step) {}
}start[N*4];
int tot, maxd;
int n, m;
char grid[N][N];
bool vis[N][N], zero[N*4];
bool error(int x, int y) {
if(x < 0 || x >= n || y < 0 || y >= m)
return true;
return false;
}
void sign(int x, int y, int step) {
if(grid[x+1][y] == '0' || grid[x][y+1] == '0')
zero[step+1] = true;
}
void bfs() {
memset(vis, false, sizeof(vis));
memset(zero, false, sizeof(zero));
queue<Node> que;
int x, y, step;
for(int i = 0; i < tot; i++) {
x = start[i].x, y = start[i].y;
if(!vis[x][y]) {
vis[x][y] = true;
sign(x, y, 1);
que.push(start[i]);
}
}
while(!que.empty()) {
Node front = que.front(); que.pop();
for(int i = 0; i < 2; i++) {
x = front.x + dx[i];
y = front.y + dy[i];
step = front.step + 1;
if(error(x, y) || vis[x][y]) continue;
vis[x][y] = true;
if(zero[step] && grid[x][y] == '1') continue;
sign(x, y, step);
que.push(Node(x, y, step));
}
}
return ;
}
void dfs(int x, int y) {
if(x + y == maxd) {
for(int i = 0; i < 2; i++)
if(!error(x+dx[i], y + dy[i]))
start[tot++] = Node(x+dx[i], y+dy[i], 1);
}else if(x + y > maxd) {
maxd = x + y;
tot = 0;
for(int i = 0; i < 2; i++)
if(!error(x+dx[i], y + dy[i]))
start[tot++] = Node(x+dx[i], y+dy[i], 1);
}
int nx, ny;
for(int i = 0; i < 4; i++) {
nx = x + dx[i], ny = y + dy[i];
if(error(nx, ny) || vis[nx][ny] || grid[nx][ny] == '1') continue;
vis[nx][ny] = true;
dfs(nx, ny);
}
}
int MAIN() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) scanf("%s", grid[i]);
tot = 0; maxd = -INF;
if(grid[0][0] == '1') {
start[tot++] = Node(0, 0, 1);
bfs();
for(int i = 1; i < (n+m); i++)
printf("%d", !zero[i]);
puts("");
}else {
memset(vis, false, sizeof(vis));
dfs(0, 0);
bfs();
if(tot == 0) {
puts("0");
}else {
int end = (n+m) - maxd;
for(int i = 1; i < end - 1; i++)
printf("%d", !zero[i]);
puts("");
}
}
}
return 0;
}
const int main_stack = 16;
char my_stack[128<<20];
int main() {
__asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");
__asm__("movl %%eax, %%esp;\n"::"a"(my_stack + sizeof(my_stack) - main_stack):"%esp");
MAIN();
__asm__("movl (%%eax), %%esp;\n"::"a"(my_stack):"%esp");
return 0;
}