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