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

Posted PushyTao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[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
****************************************************************/

以上是关于[Nowcoder | UPC] 2021年度训练联盟热身训练赛第六场 Hopscotch | 最短路 bfs的主要内容,如果未能解决你的问题,请参考以下文章

UPC-2021个人训练赛第20场-部分题解

2021-07-21训练日记upc联通数(思维)|赛博朋克(唯一分解)

2021年度训练联盟热身训练赛第一场

2021年度训练联盟热身训练赛第八场 B题 Gene Tree树中所有叶结点之间的距离平方和

备战省赛组队训练赛第十六场(UPC)

2021年度训练联盟热身训练赛第七场 K题预处理加二分