牛客国庆集训派对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;
}

 

posted @ 2019-02-28 21:56  MJT12044  阅读(236)  评论(0编辑  收藏  举报