链接:https://ac.nowcoder.com/acm/problem/210758
来源:牛客网
题意:
从(sx,sy)的位置能到达所有距离小于等于d的格子
某些格子上有宝藏,每个宝藏有其特殊的能力值.
需要求x种不同能力值的宝藏的最大与最小的能力值差值的最小值.
-1表是陷阱,不能到达这个格子
思路:
BFS出从(sx,sy)到小于等于距离d每一个点的距离deep[x][y],并把这个点入队;
对于每一个出队点,判断这个位置上的能力值是否大于零(是否有宝藏),大于零就放入数组v
将收到的宝藏sort+unique去重一下
然后再遍历数组v中每个长度为x的区间,取所有区间中最大值最小值之差的最小值即可
注意特判两种输出no情况:
1.起始位置mp(sx,xy)=-1
2.获得的宝藏数小于x
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=1e3+10,inf=1e12+10;
struct node {
int x,y;
} tmp;
vector<ll> v;
int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}},t,n,m,sx,sy,d,x;
ll vis[maxn][maxn],mp[maxn][maxn],deep[maxn][maxn],ans;
void bfs() {
queue<node> q;
q.push(node {sx,sy});
vis[sx][sy]=1;
while(!q.empty()) {
tmp = q.front();
q.pop();
if(mp[tmp.x][tmp.y]>0) v.push_back(mp[tmp.x][tmp.y]);
if(deep[tmp.x][tmp.y]>=d) continue;
for(int i=0; i<4; i++) {
int nx=tmp.x+dir[i][0],ny=tmp.y+dir[i][1];
deep[nx][ny]=deep[tmp.x][tmp.y]+1;
if(nx<1 || nx>n || ny<1 || ny>m || vis[nx][ny]) continue;
q.push(node {nx,ny});
vis[nx][ny]=1;
}
}
}
int main() {
cin>>t;
while(t--) {
v.clear();
ans=inf;
memset(deep,0,sizeof(deep));
memset(vis,0,sizeof(vis));
cin>>n>>m>>sx>>sy>>d>>x;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
cin>>mp[i][j];
if(mp[i][j]==-1) vis[i][j]=1;
}
}
if(mp[sx][sy]==-1) {
cout<<"no\n";
continue;
}
bfs();
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());//去重
int len = v.size();
if(len<x) cout<<"no\n";
else {
for(int i=0; i<=len-x; i++) {
ans = min(ans,v[i+x-1]-v[i]);
}
cout<<ans<<endl;
}
}
}