EOJ:Crossing the Road
——从地图左下角到右上角需要最短的时间(有交通灯)
——搜索
——url:http://202.120.106.94/onlinejudge/problemshow.php?pro_id=446
——source:Google Code Jam
————————————————————————————————————————————————
一开始以为只可能往上和往右走,于是直接DP。
事实上由于红灯时间很长,可以绕个来回。
本题灯的熄灭时间存储比较麻烦
另外算路口通过的时间是用求模运算会快很多
#include<stdio.h>
#include<queue>
using namespace std;
#define MAXM 100
#define oo 100000000000000000LL
const int dx[4] =
{ 0, 1, 0, -1 };
const int dy[4] =
{ 1, 0, -1, 0 };
struct node
{
int x, y;
long long t;
bool operator <(const node &b) const
{
return t > b.t;
}
node()
{
}
node(int a, long long b, long long c)
{
x = a;
y = b;
t = c;
}
} u, v;
long long T[MAXM][MAXM];
long long TIME[MAXM][MAXM][3];
int n, m, C;
void readin()
{
int i, j, k;
scanf("%d%d", &n, &m);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
{
for (k = 0; k < 3; k++)
scanf("%lld", &TIME[n - i - 1][j][k]);
TIME[n - i - 1][j][2] %= (TIME[n - i - 1][j][0]
+ TIME[n - i - 1][j][1]);
}
}
long long min(long a, long long b)
{
return a < b ? a : b;
}
void work()
{
int i, j;
long long N, W, t, tmp;
priority_queue<node> q;
for (i = 0; i <= 2 * n; i++)
for (j = 0; j <= 2 * m; j++)
T[i][j] = oo;
T[0][0] = 0;
q.push(node(0, 0, 0));
while (!q.empty())
{
u = q.top();
q.pop();
if (u.t > T[u.x][u.y])
continue;
if (u.x == 2 * n - 1 && u.y == 2 * m - 1)
break;
N = TIME[u.x / 2][u.y / 2][0];
W = TIME[u.x / 2][u.y / 2][1];
t = TIME[u.x / 2][u.y / 2][2];
for (i = 0; i < 4; i++)
{
v.x = u.x + dx[i];
v.y = u.y + dy[i];
if (v.x < 0 || v.x >= 2 * n || v.y < 0 || v.y >= 2 * m)
continue;
if (((u.y % 2 == 1) && (i == 0)) || ((v.y % 2 == 1) && (i == 2)) //不过马路
|| ((u.x % 2 == 1) && (i == 1)) || ((v.x % 2 == 1) && (i
== 3)))
v.t = u.t + 2;
else if (i == 1 || i == 3)
{
tmp = t;
tmp = (tmp - (u.t) % (N + W) + N + W) % (N + W) + u.t; //过马路南北方向走
if (tmp - (N + W) <= u.t && tmp - W >= u.t + 1)
v.t = u.t + 1;
else if (N >= 1)
v.t = tmp + 1;
}
else
{
tmp = t + N;
tmp = (tmp - (u.t) % (N + W) + N + W) % (N + W) + u.t; //过马路东西方向走
if (tmp - (N + W) <= u.t && tmp - N >= u.t + 1)
v.t = u.t + 1;
else if (W >= 1)
v.t = tmp + 1;
}
if (v.t < T[v.x][v.y])
{
T[v.x][v.y] = v.t;
q.push(v);
}
}
}
printf("%lld\n", T[2 * n - 1][2 * m - 1]);
}
int main()
{
int i;
scanf("%d", &C);
for (i = 1; i <= C; i++)
{
readin();
printf("Case #%d: ", i);
work();
}
return 0;
}
浙公网安备 33010602011771号