作为一名孱弱,刷了JZ的题,发现自己是如何的弱~~~~~~~
题目描述
给定一个一定存在从起点到终点的路径的四联通迷宫。已知Tar左右方向移动的时间为1,上下移动的时间为未知实数v。求当Tar从起点到终点的最短移动时间为已知实数L时,未知实数v是多少。
Input
输入数据包含多个测试点。第一行为一个整数T,表示测试点的数目。
对于每一个测试点,第一行包含实数L和两个整数R,C。R为迷宫的上下长度,C为迷宫的左右长度。
之后的R行,每行包含C个字符。其中空格表示空地,S表示起点,E表示终点,#表示围墙。
Output
对于每一个测试点,在单独的一行内输出未知实数v,输出保留5位小数。
样例
输入
2
2.5 4 5
#####
#S #
# E#
#####
21 13 12
############
#S## #E#
# ## # # #
# # # # #
### # # # #
# # # # #
# ## # # #
## # # # #
### # # # #
## # # # #
# ## # #
# # #
############
输出
0.50000
0.21053
Data Constraint
20%的数据,1≤ R,C ≤ 10。
100%的数据,1≤ R,C ≤ 100,0≤ v <10。
本人感受:
这道题做完交后只有90分,孱弱的我找了半个小时没发现哪里出错,只能先去吃饭,下午回来拿到数据检查了一下,(嗯嗯~~~又掉进坑里了~~~~~)这是个巨坑,不过数据还是挺给力的,三个坑都在同一个点,所以才90分,不然,呵呵呵呵呵呵呵呵呵呵呵。
解析:
别人都是二分+bfs,而我是直接上bfs,时间8ms+空间468KB。
从起点开始扫,开个数据结构struct node{int y,x,cnty,cntx},分别记录坐标和向上下、左右走的步数(用于计算答案)。
根据题意得出:1*t.cntx+ans*t.cnty = l; 所以ans = (double)(l-t.cntx)/t.cnty;
注意:1、题目数据提到答案是0<=v<10,所以需要判定if(ans>=0),(被这个坑了一个点),<0就把终点a[ey][ex]标记为0且退出这层循环(不退出会导致循环继续从终点走向剩下的路,剩下的路中就包含正确的路,将会得不到答案)。
2、这是一个小tips,注意二维数据的哪一维对应y,x,(身边的大神开始也犯了这个问题。。)建议a[y][x],注意我的q.push((node){yy,xx,cnty,cntx})与定义时一一对应,不然有bug。
最后附上愚人的代码(羸弱)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define re register int
using namespace std;
const int maxn = 105;
int a[maxn][maxn],t,n,m,sx,sy,ex,ey;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
double l,ans;
char c;
struct node{
int y,x,cnty,cntx;
};
inline char readc(){ //快速读入
char ch = getchar();
while(!(ch=='#'||ch=='S'||ch=='E'||ch==' ')) ch =getchar();
return ch;
}
double bfs(){
queue<node> q;
q.push((node){sy,sx,0,0});
a[sy][sx] = 1;
node t;
re yy,xx;
while(!q.empty()){
t = q.front();
q.pop();
if(t.y == ey&&t.x ==ex){ //比较喜欢先压入队列,取出来在判断终点
ans = (double)(l-t.cntx)/t.cnty;
if(ans>=0){
return ans;
}else{
a[t.y][t.x] = 0;//****防止首先扫到的解不是正数,并且它会
continue; //从终点扫向另一条路(正解)导致另一条路
} //的解无法得到
}
for(re i=0; i<=3; i++){
yy = t.y+dy[i];
xx = t.x+dx[i];
if(xx<1||yy<1||xx>m||yy>n||a[yy][xx]) continue;
a[yy][xx] = 1;
if(dx[i]!=0) q.push((node){yy,xx,t.cnty,t.cntx+1});
if(dy[i]!=0) q.push((node){yy,xx,t.cnty+1,t.cntx});
}
}
return 0;
}
int main(){
freopen("maze.in","r",stdin);
freopen("maze.out","w",stdout);
scanf("%d",&t);
while(t--){
scanf("%lf%d%d",&l,&n,&m);
memset(a,0,sizeof(a));
for(re i=1; i<=n; i++){
for(re j=1; j<=m; j++){
c = readc();
if(c == ' ') continue;
if(c == '#') a[i][j] = 1;
if(c == 'S') sy=i,sx=j;
if(c == 'E') ey=i,ex=j;
}
}
printf("%.5f\n",bfs());
}
return 0;
}