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 表示最少所需要的步驟。首先,先想一下暴力的其中之乙個解法,我們可以列舉使用「穿越」的那條邊的起點和終點。所以我們可以bfs從起點s跑,和終點t跑,然後取列舉的最小值,然後輸出答案就是了。接下來 t + 1 行,每行輸出兩個整數 xi,yixi,yi,中間以空格分隔, 表示每一步所經過的座標。其中,第一行和最後一行應分別對應起點和終點。
特別地,如果沒有可以走到終點的方案,則在一行輸出 -1。
答案不唯一,任何符合要求的答案都會被判為正確。
上述做法的時間複雜度為
但是,我們可以想辦法去把這個
我們想知道這個點出去的
我們可以跑乙個單調遞增的單調佇列/棧,先從左往右跑,再從右往左,如此,就可以確定每一行的在範圍
然後就是各種維護了,**較長,慎讀。
#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題 虛樹
一開始的時候,我往長鏈剖分上去寫,但是寫不好,最後寫成了當只有一條鏈的時候是 然後,開始想別的想法了,於是想 到了虛樹的做法。因為,我們可以發現,乙個點,向上影響的時候,只有同等深度的才會同時起作用,只要不是同等深度的時候,那麼他們的時間就會是錯開的,所以,我們可以對深度來進行處理。只有發生這種情況...