牛客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;
}
posted @ 2022-04-20 20:27  zyy2001  阅读(33)  评论(0编辑  收藏  举报