Walk Out
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
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.
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.
Input
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.
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.
Output
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).
Sample Input
2 2 2 11 11 3 3 001 111 101
Sample Output
111 101
Author
XJZX
Source
/*************************************************************/
题意:一个由字符'0'、'1'组成的n*m的迷宫,起点在左上角(1,1),终点在右下角(n,m),每次探险者可以往上下左右四个方向移动,并且记下当前位置的字符。到达终点后,他会得到一个二进制数(即探险者记录下来的字符串),要求探险者如何走能得到最小的二进制数,输出该二进制数(不含前导0,若字符串每个字符都为'0',则输出'0')。
解题思路:
广搜(BFS)+贪心,要使得到的二进制数最小,而且不包括前导0,那么我们很容易就可以想到遇到1之前都走0,走到距离终点最近的位置(即与终点曼哈顿距离最小的点,亦或者说x+y(x,y为当前位置的坐标)尽可能大的点)使得后面的路径尽可能短。
①先是bfs找到离目标最近的距离;
②后用贪心的思想让靠前的字符尽可能为0。
策略是每往前走一步,判断是否
可以是0,有0就走0,没0才走1,直到终点。
给几组测试数据
100
5 5
01101
00011
01111
11111
11110
100
1 1
1
100
1 1
0
100
5 5
10011
11010
00111
11111
00010
100
5 5
00011
11011
10011
11011
00001
闲话不多说,上AC代码,用时140Ms
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 1005;
const int inf = 1000000000;
char s[N][N];
bool v[N][N];
int g[4][2]={{0,1},{1,0},{0,-1},{-1,0}},n,m,a,b;
struct node
{
int x,y;
node(){}
node(int x1,int y1):x(x1),y(y1){}
};
void BFS(int x,int y)
{
memset(v,false,sizeof(v));
v[x][y]=true;
if(s[x][y]=='1')
{
a=b=1;
return ;
}
int i,Max=0;
queue<node> q;
q.push(node(x,y));
while(!q.empty())
{
for(i=0;i<4;i++)
{
x=q.front().x+g[i][0];
y=q.front().y+g[i][1];
if(!v[x][y]&&x>0&&y>0&&x<=n&&y<=m&&s[x][y]=='0')
{
v[x][y]=true;
q.push(node(x,y));
}
}
if(q.front().x+q.front().y>Max)
a=q.front().x,b=q.front().y,Max=q.front().x+q.front().y;
q.pop();
}
}
int main()
{
int t,i,j,k,l,x,y;
bool flag;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%s",s[i]+1);
BFS(1,1);
if(n+m==2)
{
printf("%c\n",s[1][1]);
continue;
}
else if(a+b==n+m)
{
puts("0");
continue;
}
// printf("%d %d\n",a,b);
if(a+b==2)
printf("1");
for(i=a+b;i<n+m;i++)
{
for(j=1;j<=n;j++)
{
k=i-j;
flag=false;
if(k>0&&v[j][k])
{
for(l=0;l<2;l++)
{
x=j+g[l][0];
y=k+g[l][1];
if(x>0&&y>0&&x<=n&&y<=m&&s[x][y]=='0')
flag=true;
}
}
if(flag)
break;
}
if(flag)
printf("0");
else
printf("1");
for(j=1;j<=n;j++)
{
k=i-j;
if(k>0&&v[j][k])
{
for(l=0;l<2;l++)
{
x=j+g[l][0];
y=k+g[l][1];
if(x>0&&y>0&&x<=n&&y<=m&&(flag&&s[x][y]=='0'||!flag))
v[x][y]=true;
}
}
}
}
puts("");
}
return 0;
}
菜鸟成长记

本文探讨了在一个由字符 '0' 和 '1' 组成的 n*m 迷宫中,从左上角出发到达右下角的最短路径。通过广搜算法寻找离终点最近的点,并采用贪心策略,确保路径上的数字以尽可能少的 '1' 开始,从而得到最小的二进制表示。特别关注于如何在有限的步骤内优化路径选择,以获得最优的二进制编码结果。
893

被折叠的 条评论
为什么被折叠?



