牛客IOI周赛21-普及组
比赛链接
牛客IOI周赛21-普及组
D.瞎位移群岛
题目描述
牛牛为了小便宜参加了 不坑你坑谁旅行社 的夏威夷群岛旅游
牛牛到了才发现这不是夏威夷群岛而是瞎位移群岛!!!
瞎位移群岛的k个岛分布在一个n*m的地图上
其中左下角为(1,1) 右上角为 (n,m)n为横坐标,m为纵坐标
牛牛降落在编号为s的岛,他要去编号为t的岛才能得救
但是牛牛的密度比水大(不会游泳)
他只能从一个岛跳到相邻的岛(上下左右相邻,即两个岛之间不能有水)
(做为一只灵活的牛,跳到另一个岛的时间可以忽略【移动时间不计】)
每一秒,瞎位移群岛有且只有一个岛发生位移,而且只位移一个单位
(如果将要位移的位置有岛了,或出地图了则此岛位移失败,位置不发生变化)
牛牛通过了一些方法得到了未来T秒瞎位移群岛的位移情况
对于每一秒有2个参数 x,y
代表第x个岛向y方向位移,若岛的位置在(a,b)
y==1 向上位移 即位移到(a,b+1)
y==2 向下位移 即位移到(a,b-1)
y==3 向左位移 即位移到(a-1,b)
y==4 向右位移 即位移到(a+1,b)
牛牛想知道在至少哪个时刻可以到达t岛
如果无法在T秒内到达t岛 输出 -1
输入描述:
第1行 n,m,k,s,t
接下来k行,\(x_i,y_i\) 代表第i个岛的坐标(保证两个岛不会在同一个位置)
一个数T
接下来T行 见题目描述
输出描述:
一行答案
示例1
输入
4 4 3 1 3
1 1
1 3
1 4
2
2 2
2 1
输出
2
备注:
对于 10% 的数据
n,m<=10
k<=10
T<=100
对于 30% 的数据
n,m<=20
k<=100
T<=5000
对于 50% 的数据
n,m<=100
k<=1000
T<=500000
对于 100% 的数据
n,m<=1e3
k<=1e3
T<=1e6
解题思路
bfs,思维
注意:移动不需要花费时间
用一个数组记录哪些岛是可以到达的,并用 \(map\) 将岛的位置映射为岛的编号,每次移动一个岛时,如果其本身可到达或者移动后会被更新为可到达,则更新周围存在岛为可到达,当终点可达时此时为最短可到达时刻
- 时间复杂度:\(O(klogk+T)\)
代码
// Problem: 瞎位移群岛
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/9799/D
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include <bits/stdc++.h>
// #define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
const int N=1005;
int n,m,k,s,t,T;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
int ddx[]={0,0,0,-1,1},ddy[]={0,1,-1,0,0};
PII a[N];
bool v[N];
map<PII,int> mp;
void bfs(int s)
{
queue<PII> q;
q.push({a[s].fi,a[s].se});
while(q.size())
{
auto p=q.front();
q.pop();
int x=p.fi,y=p.se;
for(int i=0;i<4;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(mp.find({nx,ny})!=mp.end()&&!v[mp[{nx,ny}]])
{
v[mp[{nx,ny}]]=true;
q.push({nx,ny});
}
}
}
}
int main()
{
help;
cin>>n>>m>>k>>s>>t;
for(int i=1;i<=k;i++)
cin>>a[i].fi>>a[i].se,mp[{a[i].fi,a[i].se}]=i;
v[s]=true;
bfs(s);
if(v[t])
{
puts("0");
return 0;
}
cin>>T;
for(int i=1;i<=T;i++)
{
int id,d;
cin>>id>>d;
int x=a[id].fi,y=a[id].se;
int nx=x+ddx[d],ny=y+ddy[d];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&mp.find({nx,ny})==mp.end())
{
a[id]={nx,ny};
mp.erase({x,y});
mp[{nx,ny}]=id;
}
else
continue;
for(int j=0;j<4;j++)
{
int nnx=nx+dx[j],nny=ny+dy[j];
if(mp.find({nnx,nny})!=mp.end()&&v[mp[{nnx,nny}]])v[id]=true;
}
if(v[id])bfs(id);
if(v[t])
{
cout<<i;
return 0;
}
}
puts("-1");
return 0;
}