[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
n∗n,然后一个值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
****************************************************************/