POJ3037

来源:互联网 发布:淘宝联盟手机怎么推广 编辑:程序博客网 时间:2024/06/15 22:17

1.题目描述:

Skiing
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 4893 Accepted: 1304 Special Judge

Description

Bessie and the rest of Farmer John's cows are taking a trip this winter to go skiing. One day Bessie finds herself at the top left corner of an R (1 <= R <= 100) by C (1 <= C <= 100) grid of elevations E (-25 <= E <= 25). In order to join FJ and the other cows at a discow party, she must get down to the bottom right corner as quickly as she can by travelling only north, south, east, and west. 

Bessie starts out travelling at a initial speed V (1 <= V <= 1,000,000). She has discovered a remarkable relationship between her speed and her elevation change. When Bessie moves from a location of height A to an adjacent location of eight B, her speed is multiplied by the number 2^(A-B). The time it takes Bessie to travel from a location to an adjacent location is the reciprocal of her speed when she is at the first location. 

Find the both smallest amount of time it will take Bessie to join her cow friends. 

Input

* Line 1: Three space-separated integers: V, R, and C, which respectively represent Bessie's initial velocity and the number of rows and columns in the grid. 

* Lines 2..R+1: C integers representing the elevation E of the corresponding location on the grid.

Output

A single number value, printed to two exactly decimal places: the minimum amount of time that Bessie can take to reach the bottom right corner of the grid.

Sample Input

1 3 31 5 36 3 52 4 3

Sample Output

29.00

Hint

Bessie's best route is: 
Start at 1,1 time 0 speed 1 
East to 1,2 time 1 speed 1/16 
South to 2,2 time 17 speed 1/4 
South to 3,2 time 21 speed 1/8 
East to 3,3 time 29 speed 1/4

Source

USACO 2005 October Gold
2.题意概述:

给定一个M*N的网格,已知在每个网格中的点可以向上下左右四个方向移动一个单位,每个点都有一个高度值,从每个点开始移动时存在一个速度值,从A点移动到B点,则此时B点的速度为"A的速度*2^(A的高度值-B的高度值)",而A点移动到B点所用的时间则是A点开始移动的速度值的倒数。提供网格的长和宽,每个点的高度,以及在左上角的点的出发速度,问从左上角的点到右下角的点最少需要多少时间。

3.解题思路:

由于2^(h1-h2)*2^(h2-h3)=2^(h1-h3),因此其实从某个点出发的速度可以由第一个点的速度和高度差直接算出来。每个点可以扩展出上下左右四条边。以这些为条件构建一个图,用SPFA算法以左上角的点为源点求单源最短路径,就可以得到右下角的点的最短时间了。

4.AC代码:

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <algorithm>#include <functional>#include <cmath>#include <vector>#include <queue>#include <deque>#include <stack>#include <map>#include <set>#include <ctime>#define INF 0x3f3f3f3f#define maxn 100100#define N 111#define eps 1e-6#define pi acos(-1.0)#define e exp(1.0)using namespace std;const int mod = 1e9 + 7;typedef long long ll;int mp[N][N];double speed[N][N], dis[N][N];int vis[N][N];int dir[4][2] = { {1, 0}, {0, 1}, {-1, 0}, {0, -1} };int r, c;void spfa(){memset(vis, 0, sizeof(vis));deque<pair<int, int> > q;vis[0][0] = 1;dis[0][0] = 0;q.push_back(make_pair(0, 0));while (!q.empty()){int x = q.front().first;int y = q.front().second;q.pop_front();vis[x][y] = 0;for (int i = 0; i < 4; i++){int dx = x + dir[i][0];int dy = y + dir[i][1];if (dx < 0 || dy < 0 || dx >= r || dy >= c)continue;double w = 1.0 / speed[x][y];if (dis[dx][dy] > dis[x][y] + w){dis[dx][dy] = dis[x][y] + w;if (!vis[dx][dy]){vis[dx][dy] = 1;if (!q.empty() && dis[dx][dy] <= dis[q.front().first][q.front().second])q.push_front(make_pair(dx, dy));elseq.push_back(make_pair(dx, dy));}}}}}int main(){#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);long _begin_time = clock();#endifwhile (~scanf("%lf%d%d", &speed[0][0], &r, &c)){for (int i = 0; i < r; i++)for (int j = 0; j < c; j++){scanf("%d", &mp[i][j]);speed[i][j] = speed[0][0] * pow(2.0, mp[0][0] - mp[i][j]);dis[i][j] = 1e16;}spfa();printf("%.2f\n", dis[r - 1][c - 1]);}#ifndef ONLINE_JUDGElong _end_time = clock();printf("time = %ld ms.", _end_time - _begin_time);#endifreturn 0;}

0 0