迷宮 科大訊飛杯K題 BFS 單調佇列 單調棧

2021-10-05 05:19:37 字數 3020 閱讀 3201

supersodasea 在玩乙個走迷宮的遊戲。迷宮是乙個大小為 n×m的矩陣,從上到下依次給行編號為 0,1,…n−1,從左到右依次給列編號為 0,1,…,m−1。

遊戲規則很簡單:從起點出發,每步操作可以移動到上、下、左、右四個方向的空地上,直到終點。

為了增加遊戲的難度,在這個遊戲中,從起點到終點並不一定會有直接的通路。當然,相對應地,玩家可以使用名為「穿越」的技能:從一塊空地移動到距離至多為 d 另一片空地上(起點和終點也視為空地),無論中間是否有障礙。

在使用技能時的距離是指「切比雪夫距離」,即如果從 (x1​,y1​)穿越到(x2​,y2​)需要滿足 max⁡≤d。「穿越」只能最多使用一次,使用時算一步操作。

現在你需要幫 supersodasea 計算出給定的迷宮,他最少需要多少步才能到達終點,並給出乙個方案。

第一行包含 3 個整數 n, m, d (1≤n,m≤2 0001≤n,m≤2000, 0≤d≤2 0000≤d≤2000),中間以空格分隔,分別表示地圖的行數、列數和穿越的最大距離。

接下來 n 行,每行包含乙個長度為 m 的字串,表示地圖。

其中,. 表示空地,x 表示障礙,s 表示起點,t表示終點。

輸入保證有且僅有乙個起點和乙個終點。

第一行輸出乙個整數 t 表示最少所需要的步驟。

接下來 t + 1 行,每行輸出兩個整數 xi,yixi​,yi​,中間以空格分隔, 表示每一步所經過的座標。其中,第一行和最後一行應分別對應起點和終點。

特別地,如果沒有可以走到終點的方案,則在一行輸出 -1。

答案不唯一,任何符合要求的答案都會被判為正確。

首先,先想一下暴力的其中之乙個解法,我們可以列舉使用「穿越」的那條邊的起點和終點。所以我們可以bfs從起點s跑,和終點t跑,然後取列舉的最小值,然後輸出答案就是了。

上述做法的時間複雜度為

但是,我們可以想辦法去把這個

我們想知道這個點出去的

我們可以跑乙個單調遞增的單調佇列/棧,先從左往右跑,再從右往左,如此,就可以確定每一行的在範圍

然後就是各種維護了,**較長,慎讀。

#include #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include #define lowbit(x) ( x&(-x) )

#define pi 3.141592653589793

#define e 2.718281828459045

#define inf 0x3f3f3f3f

#define big_inf 0x3f3f3f3f3f3f3f3f

#define eps 1e-8

#define half (l + r)>>1

#define lsn rt<<1

#define rsn rt<<1|1

#define lson lsn, l, mid

#define rson rsn, mid+1, r

#define ql lson, ql, qr

#define qr rson, ql, qr

#define myself rt, l, r

#define mp(a, b) make_pair(a, b)

using namespace std;

typedef unsigned long long ull;

typedef unsigned int uit;

typedef long long ll;

const int maxn = 2e3 + 7;

const int dir[4][2] =

;int n, m, d, sx, sy, ex, ey, nx, ny, tx, ty;

inline bool in_map(int x, int y)

char mp[maxn][maxn];

bool vis[maxn][maxn][2];

int dis[maxn][maxn][2];

struct node

friend bool operator < (node e1, node e2)

} now;

struct recoder

} las[maxn][maxn], ans[maxn * maxn];

int stop = 0;

queueq;

void bfs(int x, int y, int op)

}}struct que_node

friend bool operator < (que_node e1, que_node e2)

} que[maxn], h[maxn][maxn], s[maxn][maxn];

int top, tail;

int main()

}for(int i=0; i=0; j--)

}for(int j=0; j= h[i][j].val) tail--;

que[tail++] = h[i][j];

s[i][j] = que[top];}}

for(int j=0; j=0; i--)

}for(int i=0; idis[i][j][0] + s[i][j].val + 1)}}

for(int i=0; idis[i][j][0] + dis[i][j][1])}}

if(ans == inf) printf("-1\n");

else

while(stop)

for(int i=0; i

bfs(tx, ty, 0);

if(!(ex == cop_x && ey == cop_y)) ans[++stop] = recoder(ex, ey);

while(!(ex == tx && ey == ty))

while(stop)

}return 0;

}

科大訊飛杯題目

蛇形矩陣 include main for i 0 i include main else break if i 10 i 10 10 i 100 10 10 s 10 printf d n i no9 資料序列 15分 問題描述 乙個正整數有可能可以被表示為n n 2 個連續正整數之和,如 15 ...

科大訊飛杯 日期小助手

作為乙個關心父母的孩子,compute 會在每年的母親節和父親節為父母準備禮物。可是粗心的他卻不記得它們的具體日期了。已知 母親節在每年 5 月的第 2 個週日 父親節在每年 6 月的第 3 個週日。現在你需要告訴他,下乙個 不包括當天 母親節或父親節是在什麼時候。第一行包含乙個整數 t t leq...

血壓遊戲 科大訊飛杯G題 虛樹

一開始的時候,我往長鏈剖分上去寫,但是寫不好,最後寫成了當只有一條鏈的時候是 然後,開始想別的想法了,於是想 到了虛樹的做法。因為,我們可以發現,乙個點,向上影響的時候,只有同等深度的才會同時起作用,只要不是同等深度的時候,那麼他們的時間就會是錯開的,所以,我們可以對深度來進行處理。只有發生這種情況...