BOJ::14461 소가 길을 건너간 이유 7

시사점

이해(x)

설계, 손 코딩(x)

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
const int MAXN = 100, inf = 0x3f3f3f;
const int dx[]={-1, 0, 1, 0, -3, 0, 3, 0, -2, -2, -1, -1, 1, 1, 2, 2},
          dy[]={0, 1, 0, -1, 0, 3, 0, -3, -1, 1, -2, 2, -2, 2, -1, 1};
using namespace std;

int n, t;
int a[MAXN][MAXN];
int dist[MAXN][MAXN];
priority_queue<pair<int,int> > pq; // sum(min), idx
void input(){
    cin >> n >> t;
    rep(i, 0, n) rep(j, 0, n) cin >> a[i][j];
    fill(&dist[0][0], &dist[0][0] + MAXN*MAXN, inf);
}
bool over(int x, int y){ return (x<0 || y<0 || x>=n || y>=n);}
void dijkstra(){
    int ans = inf;
    dist[0][0] = 0;
    pq.push({0, 0});
    while(!pq.empty()){
        int cost = -pq.top().first;
        int x = pq.top().second / n;
        int y = pq.top().second % n;
        pq.pop();
        if(dist[x][y] != cost) continue; // dijkstra
        int toN = (n-1 - x) + (n-1 - y);
        if(toN <= 2){
            ans = min(ans, cost + toN * t);
        }
        rep(i, 0, 16){
            int nx = x+dx[i], ny = y+dy[i];
            if(over(nx, ny)) continue;
            int ncost = cost + a[nx][ny] + t * 3;
            if(dist[nx][ny] > ncost){
                dist[nx][ny] = ncost;
                pq.push({-ncost, nx * n + ny});
            }
        }
    }
    cout << ans << endl;
}
void process(){
    input();
    dijkstra();
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    process();
    return 0;
}

최초 접근하였던 TLE 코드입니다.
#include<bits/stdc++.h>
#define endl '\n'
#define rep(i,a,b) for(int i=a;i<b;i++)
typedef long long ll;
const int MAXT = 1000*1000;
const int MAXN = 100;
const int MAX_aij = 100*1000;
const int  inf = 0x3f3f3f3f;
const int dx[]={-1, 0, 1, 0}, dy[]={0, 1, 0, -1};
int n, et, ex, ey;
struct cell{int x; int y; int mv; int sum_aij;
    bool operator<(const struct cell & t)const{
        return 1LL * mv * et + sum_aij > 1LL * t.mv * et + t.sum_aij;
    }
};
using namespace std;
int a[MAXN][MAXN];
int seen[MAXN][MAXN][ MAXN * MAXN ]; // [0,10^9]
priority_queue<cell> pq;
void input(){
    cin >> n >> et;
    rep(i, 0, n) rep(j, 0, n) cin >> a[i][j];
    fill(&seen[0][0][0], &seen[0][0][0] + MAXN*MAXN*MAXN*MAXN, inf);
    ex = n-1, ey = n-1;
}
bool over(int x, int y){return (x<0 || y<0 || x>=n || y>=n);}
void bfs(){
    ll ans = inf;
    pq.push({0, 0, 0, 0});
    seen[0][0][0] = 0;
    while(!pq.empty()){
        int x = pq.top().x, y = pq.top().y, mv = pq.top().mv, sum_aij = pq.top().sum_aij;
        pq.pop();
        if( x == ex && y == ey){
            ans = min(ans, 1LL * mv * et + sum_aij );
            cout << ans << endl;
            return;
        }
        rep(d, 0, 4){
            int nx = x+dx[d], ny = y+dy[d], nmv = mv+1, nsum_aij = sum_aij;
            if(over(nx, ny)) continue;
            if(nmv %3 ==0)
                nsum_aij += a[nx][ny];
            
            if(seen[nx][ny][nmv] > nsum_aij){
                    seen[nx][ny][nmv] = nsum_aij;
                    pq.push({nx, ny, nmv, nsum_aij});
                }
        }
    }
}
void process(){
    input();
    bfs();
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    process();
    return 0;
}

복잡도

구현(x)

디버깅(x)

좋은 코드

최적화