• [Nowcoder | UPC] 2021年度训练联盟热身训练赛第六场 Hopscotch | 最短路 bfs


    题目描述

    There’s a new art installation in town, and it inspires you… to play a childish game. The art installation consists of a floor with an n×n matrix of square tiles. Each tile holds a single number from 1 to k. You want to play hopscotch on it. You want to start on some tile numbered 1, then hop to some tile numbered 2, then 3, and so on, until you reach some tile numbered k. You are a good hopper, so you can hop any required distance. You visit exactly one tile of each number from 1 to k. What’s the shortest possible total distance over a complete game of Hopscotch? Use the Manhattan distance: the distance between the tile at (x1 , y1 ) and the tile at (x2 , y2 ) is |x1 − x2 | + |y1 − y2|.

    输入

    The first line of input contains two space-separated integers n (1 ≤ n ≤ 50) and k (1 ≤ k ≤ n2 ),where the art installation consists of an n×n matrix with tiles having numbers from 1 to k.
    Each of the next n lines contains n space-separated integers x (1 ≤ x ≤ k). This is the art nstallation.

    输出

    Output a single integer, which is the total length of the shortest path starting from some 1 tile and ending at some k tile, or −1 if it isn’t possible.

    样例输入

    【样例1】

    10 5
    5 1 3 4 2 4 2 1 2 1
    4 5 3 4 1 5 3 1 1 4
    4 2 4 1 5 4 5 2 4 1
    5 2 1 5 5 3 5 2 3 2
    5 5 2 3 2 3 1 5 5 5
    3 4 2 4 2 2 4 4 2 3
    1 5 1 1 2 5 4 1 5 3
    2 2 4 1 2 5 1 4 3 5
    5 3 2 1 4 3 5 2 3 1
    3 4 2 5 2 5 3 4 4 2
    

    【样例2】

    10 5
    5 1 5 4 1 2 2 4 5 2
    4 2 1 4 1 1 1 5 2 5
    2 2 4 4 4 2 4 5 5 4
    2 4 4 5 5 5 2 5 5 2
    2 2 4 4 4 5 4 2 4 4
    5 2 5 5 4 1 2 4 4 4
    4 2 1 2 4 4 1 2 4 5
    1 2 1 1 2 4 4 1 4 5
    2 1 2 5 5 4 5 2 1 1
    1 1 2 4 5 5 5 5 5 5
    

    样例输出

    【样例1】

    5
    

    【样例2】

    -1
    

    题意:
    给出一个矩阵 n ∗ n n * n nn,然后一个值k ≤ leq n2 ,对于每一个数字i ,可以到达值为i+1的任意位置(i >= 1 && i <= k-1)
    问从1->k的最短距离是多少,两个位置的距离为曼哈顿距离
    思路:
    这个题用bfs是可以的,简单建个图跑一个最短路也好

    spfa:

    int n,m;
    typedef pair<int,int> PII;
    vector<PII> a[2507];
    ll siz[maxn];
    ll pre[maxn];
    ll cnt,head[maxn];
    ll dis[maxn];
    bool vis[maxn];
    struct node {
        int u,v,nex;
        int w;
    } e[maxn << 1];
    void init() {
        cnt = 0;
        Clear(head,-1);
        Clear(dis,0x3f3f3f3f);
    }
    void add(int u,int v,int w) {
        e[cnt].u = u;
        e[cnt].v = v;
        e[cnt].w = w;
        e[cnt].nex = head[u];
        head[u] = cnt ++;
    }
    void spfa(int x) {
        queue<int> que;
        que.push(x);
        vis[x] = 1;
        dis[x] = 0;/// visit the pnt
        while(que.size()) {
            int u = que.front();
            que.pop();
            vis[u] = false;
            for(int i=head[u]; ~i; i = e[i].nex) {
                int v = e[i].v;
                if(dis[v] > dis[u] + e[i].w) {
                    dis[v] = dis[u] + e[i].w;
                    if(vis[v] == 0) {
                        vis[v] = 1;
                        que.push(v);
                    }
                }
            }
        }
    }
    int main() {
        n = read,m = read;
        init();
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                int x = read;
                a[x].push_back({i,j});
            }
        }
         
        for(int i=1; i<=m; i++) {
            siz[i] = a[i].size();
            pre[i] = pre[i-1] + siz[i];
        }
     
        for(int i=1; i<m; i++) {
            int sizi = a[i].size();
            int sizj = a[i+1].size();
            for(int ii = 0; ii < sizi; ii ++) {
                int idi = pre[i-1] + ii + 1;
                for(int jj = 0; jj<sizj; jj++) {
                    int idj = pre[i] + jj + 1;
                    int dis = abs(a[i][ii].first - a[i+1][jj].first) + abs(a[i][ii].second - a[i+1][jj].second);
                    add(idi,idj,dis);
                }
            }
        }
        ll ans = 0x3f3f3f3f;
        for(int i=0; i<a[1].size(); i++) {
            Clear(dis,0x3f3f3f3f);
            Clear(vis,0);
            spfa(i+1);
            for(int j=pre[m-1]+1; j<=pre[m]; j++) ans = min(ans,dis[j]);
        }
        if(ans >= 0x3f3f3f3f) puts("-1");
        else cout << ans << endl;
        return 0;
    }
    /**
    10 5
    5 1 3 4 2 4 2 1 2 1
    4 5 3 4 1 5 3 1 1 4
    4 2 4 1 5 4 5 2 4 1
    5 2 1 5 5 3 5 2 3 2
    5 5 2 3 2 3 1 5 5 5
    3 4 2 4 2 2 4 4 2 3
    1 5 1 1 2 5 4 1 5 3
    2 2 4 1 2 5 1 4 3 5
    5 3 2 1 4 3 5 2 3 1
    3 4 2 5 2 5 3 4 4 2
     
    **/
     
     
    /**************************************************************
        Problem: 18787
        Language: C++
        Result: 正确
        Time:905 ms
        Memory:65716 kb
    ****************************************************************/
    
  • 相关阅读:
    Nodejs
    webpack与gulp的区别
    gulpjs
    Commonjs、AMD、CMD
    建造者模式
    工厂模式
    设计模式分类
    python的接口
    Python代码教你批量将PDF转为Word
    什么是“堆”,"栈","堆栈","队列",它们的区别?
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459793.html
Copyright © 2020-2023  润新知