牛客国庆集训派对Day1 B. Attack on Titan
B. Attack on Titan
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 25; const double g2 = sqrt(2.0), INF = 1e18, eps = 1e-8; int dx[10] = {0, 0, -1, 1, 1, 1, -1, -1}; int dy[10] = {1, -1, 0, 0, -1, 1, -1, 1}; int nxt1[2000], nxt2[2000]; bool vis[N][N][2000]; double A[N][N], dis[N][N][2000], w[2000]; struct Node{ int x, y, now; double dis; bool operator < (const Node &A) const { return dis > A.dis; } }tmp[2000]; priority_queue< Node >q; int main() { int n = read(), m = read(), C = read(), cnt = 0; for (int i = 0; i <= n; ++i) for (int j = 0; j <= m; ++j) A[i][j] = read(); for (int i = -40; i <= 40; ++i) for (int j = -20; j <= 20; ++j) { double v = i + j * g2; if (v >= 0 && v <= C) w[++cnt] = v; } sort(w + 1, w + cnt + 1); for (int i = 1; i <= cnt; ++i) { for (int j = i - 1; ~j; --j) if (fabs(w[i] - w[j] - 1) < eps) { nxt1[i] = j; break; } for (int j = i - 1; ~j; --j) if (fabs(w[i] - w[j] - g2) < eps) { nxt2[i] = j; break; } } for (int i = 0; i <= n; ++i) for (int j = 0; j <= m; ++j) for (int k = 1; k <= cnt; ++k) dis[i][j][k] = INF; dis[0][0][1] = 0, q.push((Node){0, 0, 1, 0}); while (!q.empty()) { Node topp = q.top(); q.pop(); int x = topp.x, y = topp.y, now = topp.now; if (vis[x][y][now]) continue; if (x == n && y == m) { printf("%.10lf",dis[x][y][now]); return 0; } vis[x][y][now] = 1; int t = 0; if (w[now] + eps > 1) { for (int i = 0; i < 4; ++i) { int nx = x + dx[i], ny = y + dy[i]; if (nx >= 0 && nx <= n && ny >= 0 && ny <= m) tmp[++t] = (Node){nx,ny,nxt1[now],0}; } } if (w[now] + eps > g2) { for (int i = 4; i < 8; ++i) { int nx = x + dx[i], ny = y + dy[i]; if (nx >= 0 && nx <= n && ny >= 0 && ny <= m) tmp[++t] = (Node){nx,ny,nxt2[now],0}; } } double d = dis[x][y][now]; if(now<cnt) tmp[++t]=(Node){x,y,now+1,(w[now+1]-w[now])*A[x][y]}; for (int i = 1; i <= t; ++i) { if (dis[tmp[i].x][tmp[i].y][tmp[i].now] > d + tmp[i].dis) dis[tmp[i].x][tmp[i].y][tmp[i].now] = tmp[i].dis = d + tmp[i].dis, q.push(tmp[i]); } } return 0; }