牛客ioi18c
智斗恶龙
https://ac.nowcoder.com/acm/contest/7226/C
C
先bfs把所有可以访问的数字记录下,然后枚举每一个数作为区间最小的,整个区间长x,
这里特判下如果出生在陷阱或者不同数个数小于x直接no
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> pll; typedef long double db; typedef unsigned long long ull; #define fi first #define se second #define pk push_back #define mk make_pair const ll N=1e3+10, M=0, mod=9901, inf=0x3f3f3f3f3f3f3f3f, Max=5e13; const db esp=1e-7; struct Pd{ ll x,y,c; Pd(ll x=0,ll y=0,ll c=0):x(x),y(y),c(c){}; }; ll n, m, a[N][N], num[N*N], cnt, sx, sy, d, x; queue<Pd> q; bool vis[N][N]; ll dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0}; void work(){ scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&sx,&sy,&d,&x); cnt=0; for(ll i=1;i<=n;i++) for(ll j=1;j<=m;j++) scanf("%lld",&a[i][j]), vis[i][j]=0; if(a[sx][sy]==-1){ puts("no"); return ; } q.push(Pd(sx,sy,0)); vis[sx][sy]=1; while(q.size()){ Pd f=q.front(); q.pop(); ll x=f.x, y=f.y, c=f.c; if(a[x][y]!=-1&&a[x][y]!=0) num[cnt++]=a[x][y]; for(ll i=0;i<4;i++){ ll nx=x+dx[i], ny=y+dy[i]; if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&vis[nx][ny]==0&&c<d&&a[nx][ny]!=-1) vis[nx][ny]=1, q.push(Pd(nx,ny,c+1)); } } sort(num,num+cnt); cnt=unique(num,num+cnt)-num; if(cnt<x){ puts("no"); return; } ll ans=inf; for(ll i=0,j=i+x-1;j<cnt;i++,j++){ ans=min(ans,num[j]-num[i]); } if(ans==inf) puts("no"); else printf("%lld\n",ans); return ; } int main() { ll t; for(cin>>t;t--;) work(); return 0; }