Problem:
Problem E: こたつがめを燃やさないで
Problem
こたつがめは甲羅がこたつの亀です。
こたつがめはぽきた(起床する事)途端、格子状の区画に区切られているステージに閉じ込められました。このステージには、ただ一つの出口があります。
  区画は道、塀または爆弾のいずれかであり、こたつがめは上下左右に移動することで、道または爆弾の区画に侵入することができます。
  斜めには移動できません。また、塀の区画は通ることができません。ステージの外にも道の区画が無限に広がっていますが亀の天敵であるワニがいる為、通る事はできません。
こたつがめはさっさと帰宅してねね(睡眠する事)を行いたいので、このステージの出口に向かおうと思いました。
こたつの赤外線を自在に操る事ができるこたつがめは、自身の周囲8区画を同時に道に変える能力を持っています。
  しかし、その8区画と自身がいるいずれかの区画が爆弾の区画の場合、誘爆してこたつがめは炎上し、ねねどころか有名SNS「カメったー」すら出来なくなってしまうので能力を発動する事ができません。
例を図示します。イラストが配置されていない区画とこたつがめがいる区画は道の区画です。
  こたつがめの周囲8区画とはオレンジ色の区画を指します。左の図ではこたつがめの周囲8区画、および自身がいる区画に爆弾の区画は含まれていない為、能力を発動できます。
  しかし、右の図では周囲8区画、および自身がいる区画のいずれかに爆弾の区画が含まれている為、能力を発動する事ができません。
移動するコストは1区画の移動ごとに$A$、能力を発動するコストは1回あたり$B$です。道に変えた塀あたりのコストではない事に注意してください。開始地点とステージの出口は道です。
  開始地点からステージの出口に着くまでの移動するコストと能力を発動するコストの合計の最小値を出力してください。ただし、ステージの出口に到達できない場合は代わりに"INF"と出力してください。
Input
入力は以下の形式で与えられる。
$H$ $W$ $A$ $B$
$c_{1,1} \cdots c_{1,W}$
$\vdots$
$c_{H,1} \cdots c_{H,W}$
入力は$H+1$行からなる。
$1$行目には上下の長さを表す整数$H$、左右の長さを表す整数$W$、移動するコストを表す整数$A$、能力を発動するコストを表す整数$B$がそれぞれ空白区切りで与えられる。
$2$行目からの$H$行には、こたつがめが閉じ込められたステージの各区画における状態$c_{i,j}$が与えられる。
$c_{i,j}$はそれぞれ's','g','.','#','*'のいずれかからなり、区画$(i,j)$が下記のような状態であることを表す。
's' : その区画が開始地点であることを表す。
'g' : その区画がステージの出口であることを表す。
'.' : その区画が道であることを表す。
'#' : その区画が塀であることを表す。
'*' : その区画が爆弾であることを表す。
Constraints
入力は以下の条件を満たす。
$1 \le H,W,A,B \le 1000$
$3 \le H+W$
$c_{i,j} \in${'s','g','.','#','*'}
's','g'はそれぞれ1回ずつ出現する
Output
開始地点からステージの出口に着くまでの移動するコストと能力を発動するコストの合計の最小値を出力してください。ただし、ステージの出口に到達できない場合は代わりに"INF"と出力してください。
Sample input 1
4 4 1 1
g#..
#...
.*..
...s
Sample output 1
7
Sample input 2
4 4 1 1
g#..
#*..
....
...s
Sample output 2
INF
Sample input 3
2 4 1 1
###g
s###
Sample output 3
6
Sample input 4
3 3 1 10
g..
##.
s..
Sample output 4
6
Sample input 5
3 3 10 1
g..
##.
s..
Sample output 5
21

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;
using vl = vector<ll>;
template <class T> using vec = vector<T>;
template <class T> using vv = vec<vec<T>>;
template <class T> using vvv = vv<vec<T>>;
template <class T> using minpq = priority_queue<T, vector<T>, greater<T>>;
#define all(a) (a).begin(),(a).end()
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define reps(i, l, r) for(ll i = (l); i < (r); ++i)
#define rrep(i, l, r) for(ll i = (r)-1; i >= (l); --i)
#define sz(x) (ll) (x).size()
template <typename T>
bool chmax(T &a, const T& b) { return a < b ? a = b, true : false; }
template <typename T>
bool chmin(T &a, const T& b) { return a > b ? a = b, true : false; }

#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS)
class Point {
public:
    ld x;
    ld y;
    Point(ld _x = 0, ld _y = 0) : x(_x), y(_y) {}
    Point operator+(Point p) { return Point(x + p.x, y + p.y); }
    Point operator-(Point p) { return Point(x - p.x, y - p.y); }
    Point operator*(ld a) { return Point(a * x, a * y); }
    Point operator/(ld a) { return Point(x / a, y / a); }

    ld abs() { return sqrt(norm()); }
ld norm() { return x * x + y * y; }

    bool operator<(const Point& p) const {
        return !equals(x, p.x) ? x < p.x : y < p.y;
    }
    bool operator==(const Point& p) const {
        return fabs(x - p.x) < (1e-10) && fabs(y - p.y) < (1e-10);
    }
};
typedef Point Vector;
struct Segment {
    Point A;
    Point B;
};
typedef Segment Line;
class Circle {
public:
    Point C;
    ld r;
    Circle(Point C = Point(), ld r = 0.0) : C(C), r(r) {}
};
typedef vector<Point> Polygon;

struct Edge {
    ll from, to, cost;
    Edge (ll from, ll to, ll cost = 1ll) : from(from), to(to), cost(cost) {}
};
struct Graph {
    vector<vector<Edge>> G;
    Graph() = default;
    explicit Graph(ll N) : G(N) {}
    size_t size() const {
        return G.size();
    }
    void add(ll from, ll to, ll cost = 1ll, bool direct = 0) {
        G[from].emplace_back(from, to, cost);
        if (!direct) G[to].emplace_back(to, from, cost);
    }
    vector<Edge> &operator[](const int &k) {
        return G[k];
    }
};
using Edges = vector<Edge>;

void solve(){
    ll H, W, A, B; cin >> H >> W >> A >> B;
    vec<string> S(H); rep(i, H) cin >> S[i];
    const vl dx = {1, 1, 0, -1, -1, -1, 0, 1}, dy = {0, 1, 1, 1, 0, -1, -1, -1};
    vv<bool> bomb(H, vec<bool>(W, 0));
    auto check = [&](ll h, ll w)->bool{
        return (0 <= w && w < W && 0 <= h && h < H);
    };
    pll s, g;
    rep(i, H){
        rep(k, W){
            if(S[i][k] == 's') s = {i, k};
            if(S[i][k] == 'g') g = {i, k};
            if(S[i][k] == '*'){
                bomb[i][k] = 1;
                rep(t, 8){
                    ll h = i + dx[t], w = k + dy[t];
                    if(check(h, w)) bomb[h][w] = 1;
                }
            }
        }
    }
    auto idx = [&](pll p)->ll{
        return p.first * W + p.second;
    };
    vv<ll> dis(H, vl(W, 4e18));
    vv<bool> vis(H, vec<bool>(W, 0));
    dis[s.first][s.second] = 0;
    minpq<pll> pQ;
    pQ.push({0ll, idx(s)});
    while(pQ.size()){
        pll p = pQ.top(); pQ.pop();
        ll h = p.second / W, w = p.second % W, d = p.first;
        if(vis[h][w]) continue;
        vis[h][w] = 1;
        rep(t, 4){
            ll hh = h + dx[t*2], ww = w + dy[t*2];
            if(check(hh, ww)){
                if(S[hh][ww] == '#') continue;
                if(chmin(dis[hh][ww], d + A)){
                    pQ.push({d+A, hh*W+ww});
                }
            }
        }
        if(!bomb[h][w]){
            rep(t, 8){
                ll hh = h + dx[t], ww = w + dy[t];
                if(check(hh,ww)){
                    if(chmin(dis[hh][ww], d + B + A * (1 + t % 2))){
                        pQ.push({d + B + A * (1 + t % 2), hh * W + ww});
                    }
                }
            }
        }
    }
    if(!vis[g.first][g.second]){
        cout << "INF" << endl;
        return;
    }
    cout << dis[g.first][g.second] << endl;
}

int main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    int t = 1;
    // cin >> t;
    while(t--){
        solve();
    }
}
accuracy: 1
time_ms: 100
memory_kb: 12648
final_rank: 5

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"

#line 6 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"

namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << std::min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(std::abs(a),std::abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(std::vector<T> &v){
    std::sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"

struct grid {
    int h, w;
    grid (int _h = 0, int _w = 0) : h(_h), w(_w) {}
    int idx(int x, int y) const {
        return x * w + y;
    }
    std::pair<int,int> pos(int id) const {
        return {id / w, id % w};
    }
    bool operator()(int x, int y) const {
        return 0 <= x && x < h && 0 <= y && y < w;
    }
    bool operator()(int id) const {
        return operator()(id / w, id % w);
    }
    static constexpr std::array<std::pair<int,int>, 4> dxys = {std::pair<int,int>{0, 1}, {-1, 0}, {0, -1}, {1, 0}};
    auto adj4(int x, int y) const {
        return dxys | std::views::transform([x, y](std::pair<int,int> dxy){
            return std::pair<int,int>(dxy.first + x, dxy.second + y);
        }) | std::views::filter([this](std::pair<int,int> xy){
            return operator()(xy.first, xy.second);
        });
    }
    auto adj4(int id) const {
        return adj4(id / w, id % w) | std::ranges::views::transform([this](std::pair<int,int> xy){
            return idx(xy.first, xy.second);
        });
    }
    static constexpr std::array<std::pair<int,int>, 8> dxys8 = {std::pair<int,int>{0, 1}, {-1, 0}, {0, -1}, {1, 0}, {1,1},{1,-1},{-1,1},{-1,-1}};
    auto adj8(int x, int y) const {
        return dxys8 | std::views::transform([x, y](std::pair<int,int> dxy){
            return std::pair<int,int>(dxy.first + x, dxy.second + y);
        }) | std::views::filter([this](std::pair<int,int> xy){
            return operator()(xy.first, xy.second);
        });
    }
};

void solve(){
    int h, w; in(h,w);
    grid gr(h,w);
    int a, b; in(a,b);
    vector<string> g(h); in(g);
    auto find = [&](char c){
        rep(i,h) rep(j,w){
            if (g[i][j] == c){
                return pii(i,j);
            }
        }
        abort();
    };
    auto [sx, sy] = find('s');
    auto [gx, gy] = find('g');
    // out(sx,sy,gx,gy);
    priority_queue<pli,vector<pli>,greater<pli>> pque;
    vector<ll> dist(h*w,linf);
    dist[gr.idx(sx,sy)] = 0;
    pque.emplace(0,gr.idx(sx,sy));
    while (!pque.empty()){
        auto [d, xy] = pque.top(); pque.pop();
        if (dist[xy] < d) continue;
        auto [x, y] = gr.pos(xy);
        for (auto [nx, ny] : gr.adj4(x,y)){
            if (g[nx][ny] == '#') continue;
            int nxy = gr.idx(nx,ny);
            if (chmin(dist[nxy],d+a)){
                pque.emplace(dist[nxy],nxy);
            }
        }
        bool ok = true;
        for (auto [nx, ny] : gr.adj8(x,y)){
            if (g[nx][ny] == '*') ok = false;
        }
        if (ok && g[x][y] != '*'){
            for (auto [nx, ny] : gr.adj8(x,y)){
                int nxy = gr.idx(nx,ny);
                int cost = (abs(x-nx)+abs(y-ny))*a + b;
                // out(x,y,nx,ny,cost);
                if (chmin(dist[nxy],d+cost)){
                    pque.emplace(dist[nxy],nxy);
                }
            }
        }
    }
    int gxy = gr.idx(gx,gy);
    if (dist[gxy] == linf){
        out("INF");
        return ;
    }
    out(dist[gxy]);
    // out(dist);
}

int main(){
    int t = 1; //in(t);
    while (t--) { solve(); }
}
accuracy: 1
time_ms: 70
memory_kb: 12332
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;
const ll ILL=2167167167167167167;
const int INF=2100000000;
#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define all(p) p.begin(),p.end()
template<class T> using _pq = priority_queue<T, vector<T>, greater<T>>;
template<class T> int LB(vector<T> &v,T a){return lower_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> int UB(vector<T> &v,T a){return upper_bound(v.begin(),v.end(),a)-v.begin();}
template<class T> bool chmin(T &a,T b){if(b<a){a=b;return 1;}else return 0;}
template<class T> bool chmax(T &a,T b){if(a<b){a=b;return 1;}else return 0;}
template<class T> void So(vector<T> &v) {sort(v.begin(),v.end());}
template<class T> void Sore(vector<T> &v) {sort(v.begin(),v.end(),[](T x,T y){return x>y;});}
bool yneos(bool a,bool upp=false){if(a){cout<<(upp?"YES\n":"Yes\n");}else{cout<<(upp?"NO\n":"No\n");}return a;}
template<class T> void vec_out(vector<T> &p,int ty=0){
    if(ty==2){cout<<'{';for(int i=0;i<(int)p.size();i++){if(i){cout<<",";}cout<<'"'<<p[i]<<'"';}cout<<"}\n";}
    else{if(ty==1){cout<<p.size()<<"\n";}for(int i=0;i<(int)(p.size());i++){if(i) cout<<" ";cout<<p[i];}cout<<"\n";}}
template<class T> T vec_min(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmin(ans,x);return ans;}
template<class T> T vec_max(vector<T> &a){assert(!a.empty());T ans=a[0];for(auto &x:a) chmax(ans,x);return ans;}
template<class T> T vec_sum(vector<T> &a){T ans=T(0);for(auto &x:a) ans+=x;return ans;}
int pop_count(long long a){int res=0;while(a){res+=(a&1),a>>=1;}return res;}
template<class T> T square(T a){return a * a;}


void solve();
// POP'N ROLL MUSIC / TOMOO
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t = 1;
    // cin >> t;
    rep(i, 0, t) solve();
}

void solve(){
    int H, W, A, B;
    cin >> H >> W >> A >> B;
    vector<string> S(H);
    rep(i, 0, H) cin >> S[i];
    _pq<pair<int, pair<int, int>>> pq;
    vector seen(H, vector<int>(W, INF));
    rep(i, 0, H) rep(j, 0, W) if (S[i][j] == 's') pq.push({0, {i, j}}), seen[i][j] = 0;
    vector<int> dx = {0, 0, 1, -1, 1, 1, -1, -1, 0};
    vector<int> dy = {1, -1, 0, 0, 1, -1, 1, -1, 0};
    auto f = [&](int a, int b) -> bool {
        return 0 <= a && a < H && 0 <= b && b < W;
    };
    while (!pq.empty()){
        auto [c, pos] = pq.top();
        pq.pop();
        auto [x, y] = pos;
        if (seen[x][y] != c) continue;
        // cout << c << " " << x << " " << y << endl;
        rep(k, 0, 4){
            int a = dx[k] + x;
            int b = dy[k] + y;
            if (f(a, b) && S[a][b] != '#' && chmin(seen[a][b], c + A)){
                pq.push({seen[a][b], {a, b}});
            }
        }
        {
            bool ok = true;
            rep(k, 0, 9){
                int a = dx[k] + x;
                int b = dy[k] + y;
                if (f(a, b) && S[a][b] == '*') ok = false;
            }
            if (ok) rep(k, 0, 8){
                int a = dx[k] + x;
                int b = dy[k] + y;
                if (f(a, b)){
                    int tmp = c + B + A * (abs(dx[k]) + abs(dy[k]));
                    if (chmin(seen[a][b], tmp)){
                        pq.push({seen[a][b], {a, b}});
                    }
                }
            }
        }
    }
    rep(i, 0, H) rep(j, 0, W) if (S[i][j] == 'g'){
        if (seen[i][j] == INF) cout << "INF\n";
        else cout << seen[i][j] << "\n";
    }
}
accuracy: 1
time_ms: 100
memory_kb: 8080
final_rank: 3

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
using ll = long long;
using P = pair<ll, int>;

int main(){
    int h, w, a, b; cin >> h >> w >> a >> b;
    vector<string> s(h);
    for(auto &it: s) cin >> it;

    vector<vector<ll>> mem(h, vector<ll>(w, 1LL << 60));
    priority_queue<P, vector<P>, greater<P>> Q;
    auto enc = [&w](int i, int j){
        return i*w+j;
    };
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            if(s[i][j] == 's'){
                mem[i][j] = 0;
                Q.emplace(0, enc(i, j));
            }
        }
    }
    const vector<int> dx = {0, 1, 0, -1, 1, 1, -1, -1}, dy = {1, 0, -1, 0, -1, 1, -1, 1};
    auto isin = [&h, &w](int i, int j){
        return 0 <= i && i < h && 0 <= j && j < w;
    };
    while(!Q.empty()){
        auto c = Q.top(); Q.pop();
        int ci = c.second/w, cj = c.second%w;
        for(int k = 0; k < 4; k++){
            int ni = ci+dx[k], nj = cj+dy[k];
            if(!isin(ni, nj) || s[ni][nj] == '#') continue;
            if(mem[ni][nj] > mem[ci][cj]+a){
                mem[ni][nj] = mem[ci][cj]+a;
                Q.emplace(mem[ni][nj], enc(ni, nj));
            }
        }
        bool isbeam = true;
        if(s[ci][cj] == '*') isbeam = false;
        for(int k = 0; k < 8; k++){
            int ni = ci+dx[k], nj = cj+dy[k];
            if(isin(ni, nj) && s[ni][nj] == '*') isbeam = false;
        }
        if(!isbeam) continue;
        for(int kk = 0; kk < 2; kk++){
            for(int k = 0; k < 4; k++){
                int ni = ci+dx[k+kk*4], nj = cj+dy[k+kk*4];
                if(!isin(ni, nj)) continue;
                if(mem[ni][nj] > mem[ci][cj]+a*(kk+1)+b){
                    mem[ni][nj] = mem[ci][cj]+a*(kk+1)+b;
                    Q.emplace(mem[ni][nj], enc(ni, nj));
                }
            }
        }
    }

    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            if(s[i][j] == 'g'){
                if(mem[i][j] == 1LL << 60) cout << "INF" << endl;
                else cout << mem[i][j] << endl;
            }
        }
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 12700
final_rank: 9

code_snippet: #include <cstdio>
#include <vector>
#include <queue>
#include <utility>
#include <complex>

using namespace std;

int H,W,A,B;

char maze[1003][1003];
bool visited[1003][1003];

struct S{
    int d;
    complex<int> p;
};

int operator > (const S& a,const S& b){
    return a.d>b.d;
}

int main(){

    scanf("%d%d%d%d",&H,&W,&A,&B);

    for(int i=1;i<=H;i++) scanf("%s",maze[i]+1);
    complex<int> s,g;
    for(int i=1;i<=H;i++)
        for(int j=1;j<=W;j++)
            if (maze[i][j]=='s') s={i,j},maze[i][j]='.';
            else if (maze[i][j]=='g') g={i,j},maze[i][j]='.';

    complex<int> d[]={{0,-1},{0,1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
    priority_queue<S,vector<S>,greater<S>> q;

    q.push(S{0,s});

    while(!q.empty()){
        auto cur=q.top();
        auto p=cur.p;

        if (p==g) break;
        q.pop();

        auto &vis=visited[p.real()][p.imag()];
        if (vis) continue;
        vis=true;

        bool bomb=false;
        for(int i=-1;i<=1;i++) 
            for(int j=-1;j<=1;j++){
                complex<int> diff{i,j};
                auto c=p+diff;
                if (maze[c.real()][c.imag()]=='*') bomb=true;
        }

        for(int i=0;i<4;i++) {
            auto diff=d[i];
            auto c=p+diff;
            auto m=maze[c.real()][c.imag()];
            auto dist=abs(diff.real())+abs(diff.imag());
            if (m=='.'||m=='*') {
                q.push(S{cur.d+A,c});
            }
        }

        for(int i=0;i<8&&!bomb;i++) {
            auto diff=d[i];
            auto c=p+diff;
            auto m=maze[c.real()][c.imag()];
            auto dist=abs(diff.real())+abs(diff.imag());
            
            if (m)
                q.push(S{cur.d+A*dist+B,c});
            
        }

    }

    if (q.empty()) puts("INF");
    else printf("%d\n",q.top().d);

    return 0;
}
accuracy: 1
time_ms: 490
memory_kb: 4756
final_rank: 16

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort((c).begin(), (c).end())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-7, PI = acos(-1);
//ここから編集

int dxy[5] = {-1,0,1,0,-1};
int main()
{
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(6);

  ll h, w, a, b; cin >> h >> w >> a >> b;
  vector<string> f;

  int sy,sx,gy,gx;
  REP(i,h){
    string s; cin >> s;
    f.push_back(s);
    REP(j,w){
      if(s[j] == 's'){
        sy = i;
        sx = j;
      }else if(s[j] == 'g'){
        gy = i;
        gx = j;
      }
    }
  }

  vector<vector<ll>> dist(h, vector<ll>(w, INT_MAX));

  dist[sy][sx] = 0;
  priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> pq;
  pq.push(make_pair(0, sy*w+sx));

  while(pq.size()){
    auto p = pq.top();
    pq.pop();

    int y = p.second/w, x = p.second%w;
    if(dist[y][x] < p.first) continue;

    for(int i=0; i<4; i++){
      int ny = y + dxy[i], nx = x + dxy[i+1];
      if(ny >= 0 && ny < h && nx >= 0 && nx < w && f[ny][nx] != '#'){
        if(dist[ny][nx] > dist[y][x] + a){
          dist[ny][nx] = dist[y][x] + a;
          pq.push(make_pair(dist[ny][nx], ny*w+nx));
        }
      }
    }

    bool check = true;
    for(int i=-1; i<=1; i++){
      for(int j=-1; j<=1; j++){
        int ny = y+i, nx = x+j;
        if(ny >= 0 && ny < h && nx >= 0 && nx < w){
          if(f[ny][nx] == '*') check = false;
        }
      }
    }
    if(check){
      for(int i=-1; i<=1; i++){
        for(int j=-1; j<=1; j++){
          int ny = y+i, nx = x+j;
          if(ny >= 0 && ny < h && nx >= 0 && nx < w){
            if(abs(i) == 1 && abs(j) == 1){
              if(dist[ny][nx] > dist[y][x] + b + 2*a){
                dist[ny][nx] = dist[y][x] + b + 2*a;
                pq.push(make_pair(dist[ny][nx], ny*w+nx));
              }
            }else{
              if(dist[ny][nx] > dist[y][x] + b + a){
                dist[ny][nx] = dist[y][x] + b + a;
                pq.push(make_pair(dist[ny][nx], ny*w+nx));
              }
            }
          }
        }
      }
    }
  }

  if(dist[gy][gx] == INT_MAX) cout << "INF" << endl;
  else cout << dist[gy][gx] << endl;

  return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 11968
final_rank: 7

code_snippet: #include<iostream>
#include<string>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>

using namespace std;

#define int long long
#define rep(i,n) for(int i = 0; i < (n); i++)
#define INF ((long long)1e18)
#define MOD ((int)1e9+7)
#define endl "\n"

#define yn(f) ((f)?"Yes":"No")
#define YN(f) ((f)?"YES":"NO")

#define MAX 1100

int cost[MAX][MAX];
string mp[MAX];
int sy, sx, gy, gx;
int H, W, A, B;
int dxy[4] = {1,-1,0,0};

string solve(){
	priority_queue<pair<int,pair<int,int>>,vector<pair<int,pair<int,int>>>, greater<pair<int,pair<int,int>>>> Q;
	
	for(int i = 0; i < H; i++){
		for(int j = 0; j < W; j++){
			cost[i][j] = INF;
		}
	}
	
	Q.push(make_pair(0,make_pair(sy,sx)));
	
	cost[sy][sx] = 0;
	
	while(!Q.empty()){
		pair<int,pair<int,int>> P = Q.top(); Q.pop();
		int y = P.second.first, x = P.second.second, tcost = P.first;
		bool b = false, w = false;
		
		// cout<<y<<" "<<x<<endl;
		// cout<<" cost "<<tcost<<" "<<mp[y][x]<<endl;
		if(tcost < cost[y][x]) continue;
		if(y == gy && x == gx) return to_string(tcost);
		
		for(int i = -1; i <= 1; i++){
			for(int j = -1; j <= 1; j++){
				if(y+i < 0 || y+i >= H || x+j < 0 || x+j >= W) continue;
				// cout<<y+i<<"  TTT "<<x+j<<endl;
				if(mp[y+i][x+j] == '*') b = true;
			}
		}
		// cout<<"GGGGG "<<endl;
		for(int i = 0; i < 4; i++){
			int ny = y + dxy[i], nx = x + dxy[3-i];
			// cout<<" ny nx "<<ny<<" "<<nx<<endl;
			if(ny < 0 || ny >= H || nx < 0 || nx >= W) continue;
			
			// if(mp[ny][nx] == '#' || mp[ny][nx] == '*') continue;
			if(mp[ny][nx] == '#') continue;
			
			// cout<<cost[ny][nx]<<"  cost"<<cost[y][x] + A<<endl;
			if(cost[ny][nx] <= cost[y][x] + A) continue;
			
			Q.push(make_pair(cost[y][x] + A,make_pair(ny,nx)));
			
			cost[ny][nx] = cost[y][x] + A;
		}
		
		if(b == true) continue;
		// cout<<"FFFFF"<<endl;
		for(int i = -1; i <= 1; i++){
			for(int j = -1; j <= 1; j++){
				if(i == j && i == 0) continue;
				int ny = y + i, nx = x + j, co = A+B;
			
				if(i&&j) co += A;
				
				if(ny < 0 || ny >= H || nx < 0 || nx >= W) continue;
			
				if(cost[ny][nx] <= cost[y][x] + co) continue;
			
				Q.push(make_pair(cost[y][x] + co,make_pair(ny,nx)));
			
				cost[ny][nx] = cost[y][x] + co;
			}
		}
		
	}
	return "INF";
}

signed main(){
	// cin.tie(0);
	// ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);
	
	
	cin>>H>>W>>A>>B;
	
	for(int i = 0; i < H; i++){
		cin>>mp[i];
		for(int j = 0; j < W; j++){
			if(mp[i][j] == 's'){
				sy = i, sx = j;
			}
			if(mp[i][j] == 'g'){
				gy = i, gx = j;
			}
		}
	}
	
	cout<<solve()<<endl;
	
	return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 12728
final_rank: 14

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 3055.cc: Don't Burn Kotatsu Turtle
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_H = 1000;
const int MAX_W = 1000;
const int INF = (int)((1LL << 31) - 1);

const int dxs[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
const int dys[] = { 0, -1, -1, -1, 0, 1, 1, 1 };

/* typedef */

struct Stat {
  int d, x, y;
  Stat() {}
  Stat(int _d, int _x, int _y): d(_d), x(_x), y(_y) {}
  bool operator<(const Stat &s) const { return d > s.d; }
  void print() { printf("Stat(%d,%d,%d)\n", d, x, y); }
};

/* global variables */

char flds[MAX_H][MAX_W + 4];
int ds[MAX_H][MAX_W], dis[8];

/* subroutines */

inline bool inside(int x, int y, int w, int h) {
  return (x >= 0 && x < w && y >= 0 && y < h);
}

/* main */

int main() {
  int h, w, a, b;
  scanf("%d%d%d%d", &h, &w, &a, &b);

  int sx, sy, gx, gy;
  for (int y = 0; y < h; y++) {
    scanf("%s", flds[y]);
    for (int x = 0; x < w; x++)
      switch (flds[y][x]) {
      case 's': flds[y][x] = '.', sx = x, sy = y; break;
      case 'g': flds[y][x] = '.', gx = x, gy = y; break;
      }
    fill(ds[y], ds[y] + w, INF);
  }

  ds[sy][sx] = 0;
  priority_queue<Stat> q;
  q.push(Stat(0, sx, sy));

  while (! q.empty()) {
    Stat u = q.top(); q.pop();
    //u.print();
    if (u.d != ds[u.y][u.x]) continue;
    if (u.x == gx && u.y == gy) break;

    int vd = u.d + a, din = 0;
    bool bmb = (flds[u.y][u.x] == '*');
    for (int di = 0; di < 8; di++) {
      int vx = u.x + dxs[di], vy = u.y + dys[di];
      if (inside(vx, vy, w, h)) {
	char &vf = flds[vy][vx];
	// normal move
	if (! (di & 1) && vf != '#' && ds[vy][vx] > vd) {
	  ds[vy][vx] = vd;
	  q.push(Stat(vd, vx, vy));
	}

	// bomb
	if (vf == '*') bmb = true;
	else if (vf == '#')
	  dis[din++] = di;
      }
    }
    //printf("  bmb=%d\n", bmb);

    if (! bmb)
      for (int i = 0; i < din; i++) {
	int di = dis[i];
	int vx = u.x + dxs[di], vy = u.y + dys[di];
	int vd = u.d + ((di & 1) + 1) * a + b;

	if (ds[vy][vx] > vd) {
	  ds[vy][vx] = vd;
	  q.push(Stat(vd, vx, vy));
	}
      }
  }

  if (ds[gy][gx] >= INF) puts("INF");
  else printf("%d\n", ds[gy][gx]);
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 8140
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
const int MAX = 1010;
int dp[MAX][MAX];
int bm[MAX][MAX];

signed main(){
  int h,w,p,q;
  cin>>h>>w>>p>>q;
  vector<string> st(h);
  for(int i=0;i<h;i++) cin>>st[i];

  memset(bm,0,sizeof(dp));

  auto in=[&](int y,int x){return 0<=y&&y<h&&0<=x&&x<w;};
  for(int i=0;i<h;i++){
    for(int j=0;j<w;j++){
      if(st[i][j]!='*') continue;
      for(int a=-1;a<=1;a++)
        for(int b=-1;b<=1;b++)
          if(in(i+a,j+b)) bm[i+a][j+b]=1;
    }
  }
    
  memset(dp,-1,sizeof(dp));
  struct T{
    int y,x,d;
    T(){}
    T(int y,int x,int d):y(y),x(x),d(d){}
    bool operator<(const T &a)const{return d>a.d;};
  };

  priority_queue<T> pq;
  for(int i=0;i<h;i++)
    for(int j=0;j<w;j++)
      if(st[i][j]=='s') pq.emplace(i,j,dp[i][j]=0);

  int dy[]={1,-1,0,0};
  int dx[]={0,0,1,-1};
  auto cmp=[&](int a,int b){return a<0||b<a;};
  while(!pq.empty()){
    T s=pq.top();pq.pop();
    int y=s.y,x=s.x,d=s.d;
    //cout<<y<<" "<<x<<":"<<d<<endl;
    if(dp[y][x]<d) continue;
    if(st[y][x]=='g'){
      cout<<d<<endl;
      return 0;
    }
    
    auto check=
      [&](int ny,int nx,int nd)->void{
        if(!in(ny,nx)||!cmp(dp[ny][nx],nd)) return;
        dp[ny][nx]=nd;
        pq.emplace(ny,nx,dp[ny][nx]);
      };
    
    for(int k=0;k<4;k++){
      int ny=y+dy[k],nx=x+dx[k];
      if(in(ny,nx)&&st[ny][nx]!='#') check(ny,nx,d+p);
    }
    
    if(bm[y][x]) continue;
    
    for(int a=-1;a<=1;a++)
      for(int b=-1;b<=1;b++)
        check(y+a,x+b,d+(abs(a)+abs(b))*p+q);
  }
  cout<<"INF"<<endl;
  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 12088
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 1005

struct Edge{

	Edge(int arg_to_row,int arg_to_col, ll arg_cost){
		to_row = arg_to_row;
		to_col = arg_to_col;
		cost = arg_cost;
	}

	int to_row,to_col;
	int cost;
};

struct Info{
	Info(int arg_row,int arg_col, ll arg_sum_cost){
		row = arg_row;
		col = arg_col;
		sum_cost = arg_sum_cost;
	}
	bool operator<(const struct Info &arg) const{
		return sum_cost > arg.sum_cost; //総コストの昇順(PQ)
	}

	int row,col;
	ll sum_cost;
};

int H,W;
int start_row,start_col,goal_row,goal_col;
int diff_row[9] = {-1,-1,-1,0,0,0,1,1,1},diff_col[9] = {-1,0,1,-1,0,1,-1,0,1};
int A,B;
char table[NUM][NUM];
vector<Edge> G[NUM][NUM];
int min_dist[NUM][NUM];


bool rangeCheck(int row,int col){

	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1){

		return true;
	}else{
		return false;
	}
}

int main(){

	scanf("%d %d %d %d",&H,&W,&A,&B);

	for(int row = 0; row < H; row++){

		scanf("%s",table[row]);
		for(int col = 0; col < W; col++){
			if(table[row][col] == 's'){

				start_row = row;
				start_col = col;
				table[row][col] = '.';

			}else if(table[row][col] == 'g'){

				goal_row = row;
				goal_col = col;
				table[row][col] = '.';
			}
		}
	}

	//各セルから、他のセルへエッジを張る
	bool is_bomb;
	int adj_row,adj_col;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){

			is_bomb = false;

			//隣接9区間に爆弾があるか調べる
			for(int i = 0; i < 9; i++){
				adj_row = row+diff_row[i];
				adj_col = col+diff_col[i];

				if(!rangeCheck(adj_row,adj_col))continue;

				if(table[adj_row][adj_col] == '*'){
					is_bomb = true;
					break;
				}
			}

			for(int i = 0; i < 9; i++){

				adj_row = row+diff_row[i];
				adj_col = col+diff_col[i];

				if(!rangeCheck(adj_row,adj_col))continue;

				switch(table[adj_row][adj_col]){
				case '.':

					if((abs(row-adj_row)+abs(col-adj_col) == 1)){ //隣

						G[row][col].push_back(Edge(adj_row,adj_col,A));

					}else{ //壁があって行けない場合あり

						if(table[row][adj_col] != '#' || table[adj_row][col] != '#'){
							G[row][col].push_back(Edge(adj_row,adj_col,2*A));
						}else{
							if(!is_bomb){
								G[row][col].push_back(Edge(adj_row,adj_col,2*A+B));
							}
						}
					}

					break;
				case '*':
					if((abs(row-adj_row)+abs(col-adj_col) == 1)){ //隣

							G[row][col].push_back(Edge(adj_row,adj_col,A));

						}else{ //壁があって行けない場合あり

							if(table[row][adj_col] != '#' || table[adj_row][col] != '#'){
								G[row][col].push_back(Edge(adj_row,adj_col,2*A));
							}
						}
					break;
				case '#':
					if(!is_bomb){
						G[row][col].push_back(Edge(adj_row,adj_col,A*(abs(row-adj_row)+abs(col-adj_col))+B));
					}
					break;
				}
			}
		}
	}

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			min_dist[row][col] = HUGE_NUM;
		}
	}

	priority_queue<Info> Q;
	min_dist[start_row][start_col] = 0;

	Q.push(Info(start_row,start_col,0));

	int next_row,next_col,next_cost;

	while(!Q.empty()){

		if(Q.top().row == goal_row && Q.top().col == goal_col){

			printf("%d\n",Q.top().sum_cost);
			return 0;

		}else if(Q.top().sum_cost > min_dist[Q.top().row][Q.top().col]){

			Q.pop();

		}else{

			for(int i = 0; i < G[Q.top().row][Q.top().col].size(); i++){

				next_row = G[Q.top().row][Q.top().col][i].to_row;
				next_col = G[Q.top().row][Q.top().col][i].to_col;
				next_cost = Q.top().sum_cost+G[Q.top().row][Q.top().col][i].cost;

				if(min_dist[next_row][next_col] > next_cost){
					min_dist[next_row][next_col] = next_cost;
					Q.push(Info(next_row,next_col,next_cost));
				}
			}

			Q.pop();
		}
	}

	printf("INF\n");

	return 0;
}
accuracy: 1
time_ms: 470
memory_kb: 234288
final_rank: 20

code_snippet: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
typedef pair<int,int>P;
typedef pair<int,P>P2;

priority_queue<P2,vector<P2>,greater<P2> >q;
int dx[]={0,1,1,1,0,-1,-1,-1};
int dy[]={-1,-1,0,1,1,1,0,-1};
int dc[]={1,2,1,2,1,2,1,2};
int off[]={1,-1};
int h,w,A,B,dp[1005][1005];
int sx,sy,gx,gy;
char s[1005][1005];

signed main(){
	r(i,1005)r(j,1005) dp[i][j] = 2000000000;

	cin>>h>>w>>A>>B;
	r(i,8) dc[i] = ( i%2? A*2:A );
	r(i,h) scanf("%s",s[i]);

	r(i,h)r(j,w){
		if( s[i][j] == 's' ) sx=j , sy=i;
		if( s[i][j] == 'g' ) gx=j , gy=i;
	}

	q.push(P2(0,P(sx,sy)));
	dp[sy][sx] = 0;

	while(!q.empty()){
		P2 p=q.top();q.pop();
		int x = p.second.first , y = p.second.second;
		int cost = p.first , f2 = (s[y][x]=='*');
		if( dp[y][x] < cost )continue;
		r(i,8){
			int nx = x+dx[i] , ny = y+dy[i];
			int ncos = cost+dc[i] , flag = 0;

			if( ny<0 || nx<0 || ny>=h || nx>=w )continue;
			if( s[ny][nx] == '*' )f2++;

			if(i%2)r(j,2){
				int T = (i+off[j]+8)%8;
				int tx = x+dx[T] , ty = y+dy[T];
				if( tx<0 || ty<0 || tx>=w || ty>=h || s[ty][tx]=='#' ) flag++;
			}

			if( flag == 2 )continue;
			if( dp[ny][nx] <= ncos )continue;
			if( s[ny][nx] == '#' )continue;

			dp[ny][nx] = ncos;
			q.push(P2(ncos,P(nx,ny)));
		}
		if( f2 )continue;
		r(i,8){
			int nx = x+dx[i] , ny = y+dy[i];
			int ncos = cost+dc[i]+B;

			if( ny<0 || nx<0 || ny>=h || nx>=w )continue;
			if( dp[ny][nx] <= ncos )continue;
			
			dp[ny][nx] = ncos;
			q.push(P2(ncos,P(nx,ny)));
		}
	}
	if( dp[gy][gx] == 2000000000 )cout<<"INF"<<endl;
	else cout<<dp[gy][gx]<<endl;
}
accuracy: 1
time_ms: 120
memory_kb: 12100
final_rank: 8

code_snippet: #include <bits/stdc++.h>
typedef long long ll;
typedef long double ld;
const int INF=1e9,MOD=1e9+7;
const ll LINF=1e18;
using namespace std;
#define int long long
//template
int d[1002][1002];
//main
signed main(){
  int H,W,A,B;cin>>H>>W>>A>>B;
  std::vector<string> s(H);
  for(int i=0;i<H;i++)cin>>s[i];
  int sx,sy,gx,gy;
  for(int i=0;i<H;i++){
    for(int j=0;j<W;j++){
      if(s[i][j]=='s'){sx=j;sy=i;}
      if(s[i][j]=='g'){gx=j;gy=i;}
    }
  }
  typedef pair<int,int> P;
  for(int i=0;i<1002;i++)for(int j=0;j<1002;j++)d[i][j]=LINF;
  queue<P> que;
  int x[8]={1,-1,0,0,1,1,-1,-1};
  int y[8]={0,0,1,-1,1,-1,1,-1};
  que.push(P(sy,sx));
  d[sy][sx]=0;
  while(que.size()){
    P p=que.front();que.pop();
    int pf=p.first,ps=p.second;
    bool bom=false;
    for(int i=max(0LL,pf-1);i<=min(H-1,pf+1);i++){
      for(int j=max(0LL,ps-1);j<=min(W-1,ps+1);j++){
        if(s[i][j]=='*')bom=true;
      }
    }
    //x[i]とy[i]逆に使った気がするけど問題はないので無視
    if(bom){
      for(int i=0;i<4;i++){
        if(pf+x[i]<0||pf+x[i]>=H||ps+y[i]<0||ps+y[i]>=W)continue;
        if(s[pf+x[i]][ps+y[i]]!='#'&&d[pf+x[i]][ps+y[i]]>d[pf][ps]+A){
          d[pf+x[i]][ps+y[i]]=d[pf][ps]+A;
          que.push(P(pf+x[i],ps+y[i]));
        }
      }
    }
    else{
      for(int i=0;i<4;i++){
        if(pf+x[i]<0||pf+x[i]>=H||ps+y[i]<0||ps+y[i]>=W)continue;
        if(s[pf+x[i]][ps+y[i]]!='#'&&d[pf+x[i]][ps+y[i]]>d[pf][ps]+A){
          d[pf+x[i]][ps+y[i]]=d[pf][ps]+A;
          que.push(P(pf+x[i],ps+y[i]));
        }
      }
      for(int i=0;i<4;i++){
        if(pf+x[i]<0||pf+x[i]>=H||ps+y[i]<0||ps+y[i]>=W)continue;
        if(d[pf+x[i]][ps+y[i]]>d[pf][ps]+A+B){
          d[pf+x[i]][ps+y[i]]=d[pf][ps]+A+B;
          que.push(P(pf+x[i],ps+y[i]));
        }
      }
      for(int i=4;i<8;i++){
        if(pf+x[i]<0||pf+x[i]>=H||ps+y[i]<0||ps+y[i]>=W)continue;
        if(d[pf+x[i]][ps+y[i]]>d[pf][ps]+A+A+B){
          d[pf+x[i]][ps+y[i]]=d[pf][ps]+A+A+B;
          que.push(P(pf+x[i],ps+y[i]));
        }
      }
    }
  }
  if(d[gy][gx]>100000000000000000)cout<<"INF"<<endl;
  else cout<<d[gy][gx]<<endl;
}
accuracy: 1
time_ms: 140
memory_kb: 11996
final_rank: 12

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
#define chmin(a, b) ((a)=min((a), (b)))
#define chmax(a, b) ((a)=max((a), (b)))
#define fs first
#define sc second
#define eb emplace_back
using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;
typedef tuple<int, int, int> T;

const ll MOD=1e9+7;
const ll INF=1e18;
const double pi=acos(-1);
const double eps=1e-10;

int dx[]={1, 1, 0, -1, -1, -1, 0, 1};
int dy[]={0, -1, -1, -1, 0, 1, 1, 1};

const int MAX_N=1002000;

vector<vector<P>> g(MAX_N);
vector<ll> dist(MAX_N, INF);
void dijkstra(int s){
    priority_queue<P, vector<P>, greater<P>> que;
    dist[s]=0;
    que.push(P(0, s));

    while(!que.empty()){
        P p=que.top(); que.pop();
        ll pcost=p.first, pv=p.second;
        if(dist[pv] < pcost) continue;

        for(int i=0; i<g[pv].size(); i++){
            P p2=g[pv][i];
            ll nv=p2.first, ncost=p2.second;
            if(dist[nv] > dist[pv] + ncost){
                dist[nv] = dist[pv] + ncost;
                que.push(P(dist[nv], nv));
            }
        }
    }
}

int main(){
    int h, w, a, b; cin>>h>>w>>a>>b;
    vector<string> c(h);
    for(int i=0; i<h; i++) cin>>c[i];

    int sy, sx, gy, gx;
    for(int i=0; i<h; i++){
        for(int j=0; j<w; j++){
            if(c[i][j]=='s'){
                sy=i, sx=j;
                c[i][j]='.';
            }
            if(c[i][j]=='g'){
                gy=i, gx=j;
                c[i][j]='.';
            }
        }
    }

    for(int i=0; i<h; i++){
        for(int j=0; j<w; j++){
            int cur=1000*i+j;

            bool isBomb=false;
            if(c[i][j]=='*') isBomb=true;
            for(int k=0; k<8; k++){
                int ny=i+dy[k], nx=j+dx[k];
                if(0<=ny && ny<h && 0<=nx && nx<w){
                    if(c[ny][nx]=='*') isBomb=true;
                }
            }

            for(int k=0; k<8; k++){
                int ny=i+dy[k], nx=j+dx[k];
                int nxt=1000*ny+nx;
                
                if(0<=ny && ny<h && 0<=nx && nx<w){
                    if(k%2==0){
                        // 上下左右の移動
                        if(c[ny][nx]=='#'){
                            if(isBomb) continue;
                            g[cur].push_back(P(nxt, a+b));
                        }
                        else{
                            g[cur].push_back(P(nxt, a));
                        }
                    }
                    else{
                        // 斜め移動
                        int pny=i+dy[k-1], pnx=j+dx[k-1];
                        int nny=i+dy[(k+1)%8], nnx=j+dx[(k+1)%8];
                        if(c[ny][nx]=='#' || c[pny][pnx]=='#' || c[nny][nnx]=='#'){
                            if(isBomb) continue;
                            g[cur].push_back(P(nxt, 2*a+b));
                        }
                        else{
                            g[cur].push_back(P(nxt, 2*a));
                        }
                    }
                }
            }
        }
    }

    dijkstra(1000*sy+sx);
    
    if(dist[1000*gy+gx]==INF) cout << "INF" << endl;
    else cout << dist[gy*1000+gx] << endl; 
}
accuracy: 1
time_ms: 410
memory_kb: 176016
final_rank: 19

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
using pint = pair<int,int>;
const int INF = 1<<29;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
bool chmin(int &a, int b) { if (a > b) {a = b; return true;} return false; }

int H, W, A, B;
vector<string> fi;

int main() {
    cin >> H >> W >> A >> B;
    fi.resize(H);
    for (int i = 0; i < H; ++i) cin >> fi[i];
    int sx, sy, tx, ty;
    for (int i = 0; i < H; ++i) for (int j = 0; j < W; ++j) {
            if (fi[i][j] == 's') sx = i, sy = j;
            if (fi[i][j] == 'g') tx = i, ty = j;
        }
    
    priority_queue<pair<int,pint>, vector<pair<int,pint> >,
                   greater<pair<int,pint> > > que;
    que.push({0, pint(sx, sy)});
    vector<vector<int> > dp(H, vector<int>(W, INF));
    dp[sx][sy] = 0;
    while (!que.empty()) {
        auto cur = que.top(); que.pop();
        int cur_dist = cur.first;
        int x = cur.second.first;
        int y = cur.second.second;
        if (cur_dist > dp[x][y]) continue;

        //cout << x << ", " << y << ": " << cur_dist << endl;

        // 通常の移動
        for (int dir = 0; dir < 4; ++dir) {
            int nx = x + dx[dir], ny = y + dy[dir];
            if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue;
            if (fi[nx][ny] == '#') continue;
            if (chmin(dp[nx][ny], dp[x][y] + A)) que.push({dp[nx][ny], pint(nx, ny)});
        }

        // 魔法
        bool can = true;
        for (int i = x-1; i <= x+1; ++i)
            for (int j = y-1; j <= y+1; ++j) {
                if (i < 0 || i >= H || j < 0 || j >= W) continue;
                if (fi[i][j] == '*') can = false;
            }
        if (can) {
            for (int i = x-1; i <= x+1; ++i)
                for (int j = y-1; j <= y+1; ++j) {
                    if (i < 0 || i >= H || j < 0 || j >= W) continue;
                    if (i == x && j == y) continue;
                    if (fi[i][j] != '#') continue;
                    if (chmin(dp[i][j], dp[x][y] + B + A * (abs(i-x) + abs(j-y))))
                        que.push({dp[i][j], pint(i, j)});
                }       
        }
    }
    if (dp[tx][ty] < INF) cout << dp[tx][ty] << endl;
    else cout << "INF" << endl;
}
accuracy: 1
time_ms: 150
memory_kb: 7744
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
#define all(x) (x).begin(),(x).end()
//#pragma GCC optimize ("-O3")
using namespace std; void _main(); int main() { cin.tie(0); ios::sync_with_stdio(false); _main(); }
typedef long long ll; const int inf = INT_MAX / 2; const ll infl = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }
//---------------------------------------------------------------------------------------------------
/*---------------------------------------------------------------------------------------------------
　　　　　　　　　　　 ∧＿∧  
　　　　　 ∧＿∧ 　（´<_｀ ）　 Welcome to My Coding Space!
　　　　 （ ´_ゝ`）　/　 ⌒i     
　　　　／　　　＼　 　 |　|     
　　　 /　　 /￣￣￣￣/　　|  
　 ＿_(__ﾆつ/　    ＿/ .| .|＿＿＿＿  
　 　　　＼/＿＿＿＿/　（u　⊃  
---------------------------------------------------------------------------------------------------*/












template<typename T> using min_priority_queue = priority_queue<T, vector<T>, greater<T>>;
int H, W, A, B;
string C[1010];
int vis[1010][1010]; ll dis[1010][1010];
min_priority_queue<pair<ll, int>> que;
enum { UP = 0, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT };
int dx[8] = { 0,1,1,1,0,-1,-1,-1 };
int dy[8] = { -1,-1,0,1,1,1,0,-1 };
//---------------------------------------------------------------------------------------------------
void _main() {
    cin >> H >> W >> A >> B;
    rep(y, 0, H) cin >> C[y];

    rep(y, 0, H) rep(x, 0, W) dis[y][x] = infl;

    int sx, sy;
    rep(y, 0, H) rep(x, 0, W) if (C[y][x] == 's') {
        sx = x;
        sy = y;
    }

    dis[sy][sx] = 0;
    que.push({ 0, sy * 1010 + sx });

    while (!que.empty()) {
        auto q = que.top(); que.pop();

        ll c = q.first;
        int x = q.second % 1010;
        int y = q.second / 1010;

        if (C[y][x] == 'g') {
            cout << dis[y][x] << endl;
            return;
        }

        if (vis[y][x]) continue;
        vis[y][x] = 1;

        rep(i, 0, 8) if ((i & 1) == 0) {
            int xx = x + dx[i];
            int yy = y + dy[i];
            if (xx < 0 or W <= xx or yy < 0 or H <= yy) continue;
            if (C[yy][xx] == '#') continue;
            if (chmin(dis[yy][xx], c + A)) que.push({ dis[yy][xx], yy * 1010 + xx });
        }

        int ok = 1;
        if (C[y][x] == '*') ok = 0;
        rep(i, 0, 8) {
            int xx = x + dx[i];
            int yy = y + dy[i];
            if (xx < 0 or W <= xx or yy < 0 or H <= yy) continue;
            if (C[yy][xx] == '*') ok = 0;
        }

        if (ok) {
            rep(i, 0, 8) {
                int xx = x + dx[i];
                int yy = y + dy[i];
                if (xx < 0 or W <= xx or yy < 0 or H <= yy) continue;
                int d = abs(x - xx) + abs(y - yy);
                if (chmin(dis[yy][xx], c + B + A * d)) que.push({ dis[yy][xx], yy * 1010 + xx });
            }
        }
    }

    cout << "INF" << endl;
}
accuracy: 1
time_ms: 120
memory_kb: 16028
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i, n) for (long long i = 0, max_i = (n); i < max_i; i++)
#define REPI(i, a, b) for (long long i = (a), max_i = (b); i < max_i; i++)
#define ALL(obj) begin(obj), end(obj)
#define RALL(obj) rbegin(obj), rend(obj)
#define fi first
#define se second
using ii = pair<int, int>;
template <class T> inline bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template <class T> inline bool chmin(T &a, const T &b) { if (a > b) { a = b; return true; } return false; }

// debug
template <class T> ostream& operator<<(ostream &s, vector<T>& d) { REP (i, d.size()) s << d[i] << (i == d.size() - 1 ? "" : " "); return s; }
template <class T> ostream& operator<<(ostream &s, vector<vector<T>>& d) { REP (i, d.size()) s << d[i] << (i == d.size() - 1 ? "" : "\n"); return s; }
template <class T, class S> ostream& operator<<(ostream &s, pair<T, S>& p) { s << "{" << p.first << ", " << p.second << "}"; return s; }
template <class T, class S> ostream& operator<<(ostream& s, map<T, S> m) { for (auto it = m.begin(); it != m.end(); it++) { s << *it << (next(it) == m.end() ? "" : "\n"); } return s; }
#ifdef _MY_DEBUG
  #define dump(...) cerr << "/* " << #__VA_ARGS__ << " :[" << __LINE__ << ":" << __FUNCTION__ << "]" << endl, dump_func(__VA_ARGS__), cerr << "*/\n\n";
#else
  #define dump(...)
#endif
void dump_func() { cerr << endl; }
template <class Head, class... Tail> void dump_func(Head&& h, Tail&&... t) { cerr << h << (sizeof...(Tail) == 0 ? "" : ", "), dump_func(forward<Tail>(t)...); }

struct Fast { Fast() { cin.tie(0); ios::sync_with_stdio(false); } } fast;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
constexpr int MOD = 1000000007;
// *************** TEMPLATE END *************** 

class DirectedGraph {
  struct Edge { int to, cost; };
public:
  vector<vector<Edge>> G;
  int V;
  DirectedGraph(int V) : G(V), V(V) {}
  void add_edge(int u, int v, int cost) {
    G[u].push_back({v, cost});
    // G[v].push_back({u, cost});
  }
  vector<int> dijkstra(int s) {
    vector<int> d(V, 1e18); d[s] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que; // {dist, v}
    que.push({0, s});
    while (!que.empty()) {
      pair<int, int> p = que.top(); que.pop();
      int v = p.second;
      if (d[v] < p.first) continue;  // 定数倍枝刈り
      for (Edge e: G[v]) {
        int tmp = d[v] + e.cost;
        if (d[e.to] <= tmp) continue;
        d[e.to] = tmp;
        que.push({tmp, e.to});
      }
    }
    return d;
  }
};

vector<ii> dirs = {
  {1, 0}, {0, 1}, {-1, 0}, {0, -1},  // 4方向
  {1, 1}, {-1, 1}, {-1, -1}, {1, -1},  // 斜め
  {0, 0},  // 自身
};

signed main() {
  int h, w, a, b; cin >> h >> w >> a >> b;
  vector<string> t(h); REP (i, h) cin >> t[i];
  ii s, g;
  REP (i, h) {
    REP (j, w) {
      if (t[i][j] == 's') s = {i, j};
      if (t[i][j] == 'g') g = {i, j};
    }
  }
  auto i2ii = [&](int i) { return ii({i / w, i % w}); };
  auto ii2i = [&](ii p) { return p.fi * w + p.se; };
  auto valid = [&](ii p) {
    return 0 <= p.fi && p.fi < h && 0 <= p.se && p.se < w;
  };
  auto around_bomb = [&](ii p) {
    for (ii dir: dirs) {
      ii to = {p.fi + dir.fi, p.se + dir.se};
      if (!valid(to)) continue;
      if (t[to.fi][to.se] == '*') return true;
    }
    return false;
  };

  DirectedGraph G(h * w);
  REP (i, h) {
    REP (j, w) {
      bool bomb = around_bomb({i, j});
      for (ii dir: dirs) {
        ii to = {i + dir.fi, j + dir.se};
        if (!valid(to)) continue;
        if (abs(dir.fi) + abs(dir.se) == 1) {
          int cost = a;
          if (t[to.fi][to.se] == '#') {
            if (bomb) continue;
            cost += b;
          }
          G.add_edge(ii2i({i, j}), ii2i(to), cost);
        } else if (abs(dir.fi) + abs(dir.se) == 2) {
          int cost = 2 * a;
          if (t[to.fi][to.se] == '#' || (t[i + dir.fi][j] == '#' && t[i][j + dir.se] == '#')) {
            if (bomb) continue;
            cost += b;
          }
          G.add_edge(ii2i({i, j}), ii2i(to), cost);
        }
      }
    }
  }
  vector<int> d = G.dijkstra(ii2i(s));
  if (d[ii2i(g)] == 1e18) {
    cout << "INF" << endl;
  } else {
    cout << d[ii2i(g)] << endl;
  }
}
accuracy: 1
time_ms: 400
memory_kb: 175720
final_rank: 18

code_snippet: #include <bits/stdc++.h>
#define fi first
#define se second
#define inf 2100000000
using namespace std;

int h, w, a, b, ans = inf;
string c[1005];
int memo[1005][1005] = {0};
bool ch[1005][1005] = {0};
pair<int, int> s, g;
int d[4] = {0, 1, 0, -1};
int ds[4] = {1, -1, -1, 1};

void solve();

int main() {
  cin >> h >> w >> a >> b;
  for(int i = 0; i < h; ++i) cin >> c[i];
  for(int i = 0; i < h; ++i)
    for(int j = 0; j < w; ++j) memo[i][j] = inf;
  for(int i = 0; i < h; ++i)
    for(int j = 0; j < w; ++j) {
      if(c[i][j] == 's') {
        s = {i, j};
        c[i][j] = '.';
        memo[i][j] = 0;
      }
      if(c[i][j] == 'g') {
        g = {i, j};
        c[i][j] = '.';
      }
    }
  for(int i = 0; i < h; ++i)
    for(int j = 0; j < w; ++j) {
      bool nowch = 1, block = 0;
      for(int k = -1; k <= 1; ++k)
        for(int l = -1; l <= 1; ++l)
          if(k + i >= 0 && k + i < h && l + j >= 0 &&
             l + j < w) {
            if(c[k + i][l + j] == '*') nowch = 0;
            if(c[k + i][l + j] == '#') block = 1;
          }
      ch[i][j] = nowch & block;
    }
  solve();
  if(ans == inf)
    cout << "INF" << endl;
  else
    cout << ans << endl;
  return 0;
}

void solve() {
  priority_queue<pair<int, pair<int, int>>,
                 vector<pair<int, pair<int, int>>>,
                 greater<pair<int, pair<int, int>>>>
      pq;
  pq.push({0, {s.fi, s.se}});
  while(!pq.empty()) {
    pair<int, pair<int, int>> now, nextp;
    now = pq.top();
    pq.pop();
    if(memo[now.se.fi][now.se.se] < now.fi) continue;
    for(int i = 0; i < 4; ++i) {
      nextp = now;
      nextp.se.fi += d[i];
      nextp.se.se += d[i ^ 1];
      nextp.fi += a;
      if(nextp.se.fi < 0 || nextp.se.fi >= h ||
         nextp.se.se < 0 || nextp.se.se >= w ||
         memo[nextp.se.fi][nextp.se.se] <= nextp.fi)
        continue;
      if(c[nextp.se.fi][nextp.se.se] == '#') {
        if(ch[now.se.fi][now.se.se] &&
           memo[nextp.se.fi][nextp.se.se] > nextp.fi + b)
          nextp.fi += b;
        else
          continue;
      }
      memo[nextp.se.fi][nextp.se.se] = nextp.fi;
      pq.push(nextp);
    }
    if(!ch[now.se.fi][now.se.se]) continue;
    for(int i = 0; i < 4; ++i) {
      nextp = now;
      nextp.se.fi += ds[i];
      nextp.se.se += ds[(i + 1) % 4];
      nextp.fi += 2 * a + b;
      if(nextp.se.fi < 0 || nextp.se.fi >= h ||
         nextp.se.se < 0 || nextp.se.se >= w ||
         c[nextp.se.fi][nextp.se.se] != '#' ||
         memo[nextp.se.fi][nextp.se.se] <= nextp.fi)
        continue;
      memo[nextp.se.fi][nextp.se.se] = nextp.fi;
      pq.push(nextp);
    }
  }
  ans = memo[g.fi][g.se];
}
accuracy: 1
time_ms: 130
memory_kb: 8956
final_rank: 10

code_snippet: #include <bits/stdc++.h>

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = std::int64_t;
using T = std::tuple<int,int,int>;

const int dx[] = {-1, +1, 0, 0, -1, -1, +1, +1, 0}, dy[] = {0, 0, -1, +1, -1, +1, -1, +1, 0};
constexpr int INF = 2001001001;

int H, W, A, B;
std::string m[1100];
int sy, sx, gy, gx;
bool has[1100][1100];
int dist[1100][1100];
std::priority_queue<T, std::vector<T>, std::greater<T>> pq;

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    std::cin >> H >> W >> A >> B;

    for(int i=0;i<H;++i){
        std::cin >> m[i];

        for(int j=0;j<W;++j){
            if(m[i][j] == 's'){
                sy = i;
                sx = j;
            }else if(m[i][j] == 'g'){
                gy = i;
                gx = j;
            }
        }
    }

    for(int i=0;i<H;++i){
        for(int j=0;j<W;++j){
            if(m[i][j] == '*'){
                for(int k=0;k<9;++k){
                    int y = i + dy[k], x = j + dx[k];

                    if(0 <= y && y < H && 0 <= x && x < W){
                        has[y][x] = true;
                    }
                }
            }
        }
    }

    std::fill(&dist[0][0], &dist[0][0] + 1100 * 1100, INF);
    dist[sy][sx] = 0;
    pq.emplace(0, sy, sx);

    until(pq.empty()){
        int d, y, x;
        std::tie(d, y, x) = pq.top();
        pq.pop();

        if(d > dist[y][x]){
            continue;
        }

        for(int i=0;i<4;++i){
            int ny = y + dy[i], nx = x + dx[i];

            if(0 <= ny && ny < H && 0 <= nx && nx < W && m[ny][nx] != '#'){
                if(d + A < dist[ny][nx]){
                    dist[ny][nx] = d + A;
                    pq.emplace(dist[ny][nx], ny, nx);
                }
            }
        }

        unless(has[y][x]){
            for(int i=0;i<8;++i){
                int ny = y + dy[i], nx = x + dx[i];

                if(0 <= ny && ny < H && 0 <= nx && nx < W && m[ny][nx] == '#'){
                    int ma = std::abs(ny - y) + std::abs(nx - x);

                    if(d + ma * A + B < dist[ny][nx]){
                        dist[ny][nx] = d + ma * A + B;
                        pq.emplace(dist[ny][nx], ny, nx);
                    }
                }
            }
        }
    }

    if(dist[gy][gx] < INF){
        std::cout << dist[gy][gx] << std::endl;
    }else{
        std::cout << "INF" << std::endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 9792
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;

const ll INF = 1LL << 60;

struct state {
  ll y, x, d;

public:
  bool operator<(const state &s) const {
    return d > s.d;
  }
};

ll dy1[4] = { -1, +0, +1, +0 };
ll dx1[4] = { +0, -1, +0, +1 };

ll dy2[4] = { -1, -1, +1, +1 };
ll dx2[4] = { -1, +1, -1, +1 };

int main(void) {
  ll H, W, A, B;
  cin >> H >> W >> A >> B;
  vector<string> S(H);
  REP(i, 0, H) cin >> S[i];

  ll sy, sx, gy, gx;
  REP(i, 0, H) REP(j, 0, W) {
    if (S[i][j] == 's') {
      sy = i;
      sx = j;
    }
    if (S[i][j] == 'g') {
      gy = i;
      gx = j;
    }
  }

  vector<vector<ll>> dp(H, vector<ll>(W, INF));
  priority_queue<state> q;
  q.push((state) { sy, sx, 0 });

  while (q.size()) {
    ll y = q.top().y, x = q.top().x, d = q.top().d;
    q.pop();

    if (dp[y][x] <= d) continue;
    dp[y][x] = d;

    REP(i, 0, 4) {
      ll ny = y + dy1[i], nx = x + dx1[i];
      if (0 <= ny && ny < H && 0 <= nx && nx < W && S[ny][nx] != '#') {
        q.push((state) { ny, nx, d + A });
      }
    }

    bool ok = true;
    REP(i, -1, 2) REP(j, -1, 2) {
      ll ny = y + i, nx = x + j;
      if (0 <= ny && ny < H && 0 <= nx && nx < W && S[ny][nx] == '*') {
        ok = false;
      }
    }
    if (ok) {
      REP(i, 0, 4) {
        ll ny = y + dy1[i], nx = x + dx1[i];
        if (0 <= ny && ny < H && 0 <= nx && nx < W) {
          q.push((state) { ny, nx, d + A + B });
        }
      }
      REP(i, 0, 4) {
        ll ny = y + dy2[i], nx = x + dx2[i];
        if (0 <= ny && ny < H && 0 <= nx && nx < W) {
          q.push((state) { ny, nx, d + A * 2 + B });
        }
      }
    }
  }

  if (dp[gy][gx] == INF) {
    cout << "INF" << endl;
  } else {
    cout << dp[gy][gx] << endl;
  }
}
accuracy: 1
time_ms: 540
memory_kb: 12436
final_rank: 17

code_snippet: //実装が重そうな問題はある程度考えてから書く
//初期化を忘れずに（特に二分探索とか）
//コーナーケースを考えて（特に場合分けとか）
//不可解すぎるバグは配列外参照（配列の長さ）を検討
#include "bits/stdc++.h"
#define YES "YES"
#define NO "NO"
#define YESNO OUT(three(solve(),YES,NO))
#define ECHO OUT(solve())
#define three(A,B,C) ((A)?(B):(C))
#define FOR(i,a,b)  for(LL i=(a);i< (LL)(b);i++)
#define EFOR(i,a,b) for(LL i=(a);i<=(LL)(b);i++)
#define RFOR(i,a,b) for(LL i=(a);i>=(LL)(b);i--)
#define REP(i,b) FOR(i,zero,b)
#define EREP(i,b) EFOR(i,zero,b)
#define RREP(i,b) RFOR(i,b-1,zero)
#define ALL(c) c.begin(),c.end()
#define UNIQUE(c) sort(ALL(c));c.erase(unique(ALL(c)),c.end())
#define MAX(c) (*max_element(ALL(c)))
#define MIN(c) (*min_element(ALL(c)))
#define MP make_pair
#define FI first
#define SE second
#define SI(x) (LL(x.size()))
#define PB emplace_back
#define DEBUG(a) OUT(a)
#define DEBUG2(a,b) OUT2(a,b)
#define cat cout << __LINE__ << endl
#define OUT(a) cout << (a) << endl
#define OUT2(a,b) cout << (a) <<" "<<(b) << endl
#define int long long
#define zero 0LL
#define pb PB
using namespace std;
template<typename T> inline bool middle(T a, T b, T c) { return b <= a && a <= c; }
template<class T> inline bool MX(T &l, const T &r) { return l < r ? l = r, 1 : 0; }
template<class T> inline bool MN(T &l, const T &r) { return l > r ? l = r, 1 : 0; }
typedef long long LL;
typedef double ld;
typedef LL ut;
typedef vector<ut> VI;
typedef vector<VI> VII;
typedef pair<ut, ut> pr;
typedef pair<ut, pr> ppr;
typedef vector<pr> Vpr;
typedef vector<ppr> Vppr;
typedef priority_queue<ppr, Vppr ,greater<ppr> > PQ;
inline void outputVI(VI x) { REP(i, SI(x)) { cout << three(i, " ", "") << x[i]; }OUT(""); }
int dx[] = { 0,1,0,-1,1,1,-1,-1,0 }, dy[] = { 1,0,-1,0,1,-1,1,-1,0 };
const int SIZE1 =3e5 + 1000;
const int SIZE2 = 2010;
const int SIZE3 = 22;
const int SIZE = SIZE1;
const LL p = 7 + 1e9;
const LL INF = 1LL << 60;
const long double EPS = 1e-7;
ut N, M, K, X, L, Y,H,W,Q,D;
// ut A,B,C,D,E,F,G,H,I,J,O,P,Q,R,T,U;
VI edges[SIZE];
LL vals[SIZE], nums[SIZE], maps[SIZE2][SIZE2], answer = zero;
//LL A[SIZE], B[SIZE];
bool nable[SIZE2][SIZE2];
LL cost[SIZE2][SIZE2];
LL A, B;
LL sy, sx, gy, gx;
LL solve() {
	cin >> H >> W >> A >> B;
	string s;
	REP(i, SIZE2) REP(j, SIZE2) cost[i][j] = INF;
	REP(i, H) {
		cin >> s;
		REP(j, W) {
			LL h=i+1, w=j+1;
			maps[h][w]=s[j]=='.';
			//cout << maps[i+1][j+1] << endl;
			if (s[j] == '*') {
				maps[h][w] = 1;
				EFOR(k, -1, 1) EFOR(l, -1, 1)
					nable[h + k][w + l] = true;
			}
			if (s[j] == 'g') {
				maps[h][w] = true;
				gy = h;
				gx = w;
			}
			else if (s[j] == 's') {
				maps[h][w] = true;
				sy = h;
				sx = w;

			}
		}
	}
	PQ qu;
	cost[sy][sx] = 0;
	qu.emplace(cost[sy][sx], pr(sy, sx));
	
	while (!qu.empty()) {
		pr now = qu.top().second;
		LL co = qu.top().first;
		qu.pop();
		LL h = now.first;
		LL w = now.second;
		if (h <= 0 or  h> H or w <= 0 or w> W) continue;
		assert(co >= cost[h][w]);
		if (co != cost[h][w]) continue;
		REP(i, 8) {
			int ny = dy[i] + h, nx = dx[i] + w;
			if (i < 4 and maps[ny][nx]) {
				if(MN(cost[ny][nx],co+A))
					qu.emplace(cost[ny][nx],pr(ny,nx));

			}
			else if (!nable[h][w]) {
				if (i < 4) {
					if (MN(cost[ny][nx], co + B+A))
						qu.emplace(cost[ny][nx],pr(ny,nx));
				}
				else {
					if (MN(cost[ny][nx], co + B + A+A))
						qu.emplace(cost[ny][nx],pr(ny,nx));
				}
			}
		}
	
	}
	if (cost[gy][gx] >= INF/2) {
		cout << "INF" << endl;
		return 0;
	}
	cout << cost[gy][gx] << endl;

	return 0;
}
signed main() {
	ios_base::sync_with_stdio(false);
	cout << fixed << setprecision(10);
	solve();
	//	cin >> N;
	return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 55428
final_rank: 15