题目链接:https://gmoj.net/senior/#main/show/1297
分析
一开始打了个暴搜挂掉了。。
后面看了题解改了个BFS,一个队列结构体记录坐标和速度,
d
i
s
[
i
]
[
j
]
dis[i][j]
dis[i][j]表示
(
1
,
1
)
(1,1)
(1,1)到
(
i
,
j
)
(i,j)
(i,j)的最小时间。
做一个类似SPFA的东西,就可以像求最短路一样求出来。
注意精度!!!(get函数手动四舍五入¿)侯哥卡精度一下午最后还是打了个小表才过
上代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<queue>
using namespace std;
int r,c;
double n,dis[105][105],ans;
int a[105][105],v[105][105];
int dx[5]={0,1,0,-1,0};
int dy[5]={0,0,1,0,-1};
struct node
{
int x,y;
double speed;
};
void bfs()
{
queue<node> q;
q.push((node){1,1,n});
while(!q.empty())
{
int x=q.front().x;
int y=q.front().y;
double val=q.front().speed,nows;
q.pop();
for(int i=1;i<=4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>0&&xx<=r&&yy>0&&yy<=c)
{
if(dis[xx][yy]>dis[x][y]+1.0/val)
{
dis[xx][yy]=dis[x][y]+1.0/val;
if(!v[xx][yy])
{
v[xx][yy]=1;
double nows=val*pow(2.0,a[x][y]-a[xx][yy]);
q.push((node){xx,yy,nows});
}
}
}
}
v[x][y]=0;
}
}
double get(double x)
{
double q;
long long w=floor(x*1000);
if(w%10<5)
{
w/=10;
q=w/100.0;
return q;
}
else if(w%10>5)
{
w/=10;q=(w+1)/100.0;
return q;
}
else
{
w/=10;
if((w%10)%2==0)
{
q=(w+1)/100.0;
return q;
}
else
{
q=w/100.0;
return q;
}
}
}
int main()
{
freopen("cowski.in","r",stdin);
freopen("cowski.out","w",stdout);
scanf("%lf%d%d",&n,&r,&c);
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
scanf("%d",&a[i][j]);
}
}
memset(dis,0x7f,sizeof(dis));
dis[1][1]=0.0;
v[1][1]=1;
bfs();
printf("%.2lf",get(dis[r][c]));
return 0;
}