1. 程式人生 > 其它 >牛客IOI周賽21-普及組

牛客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;
}