月球機器人漫步 (牛客網Wannafly挑戰賽21 B)(各種子序列都不會越界)
機器人
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld
題目描述
從前在月球上有一個機器人。
月球可以看作一個 n*m 的網格圖,每個格子有三種可能:空地,障礙,機器人(有且僅有一個),現在地面指揮中心想讓機器人在月球上行走,每次可以傳送一個指令,為 U-往上走、D-往下走、L-往左走、R-往右走的其中之一。
當機器人接收到一個行走指令時,如果即將到達的位置為障礙物,那麼機器人將留在原地,否則機器人向對應方向走一步,如果其走出邊界那麼立即死亡。
地面指揮中心當然不想讓機器人就這麼掛掉,因此其定義一個操作序列是安全的,當且僅當機器人按此操作序列走不會死亡。
但是從地球向月球發信息不是個容易的事,而且有時候某些指令還會在茫茫宇宙中被吞沒,比如指揮中心傳出去 RUR 指令,到機器人那裡就可能變成 RR 或者變成 U,因此定義一個操作序列是絕對安全的當且僅當其任意子序列都是安全的。
現在地面指揮中心想知道,對於某一個地圖,絕對安全的操作序列最長可以到多少,如果存在一個長度為正無窮的這樣的序列,那麼輸出-1。
輸入描述:
第一行一個正整數T,表示資料組數。 接下來一共 T 組資料,每組資料第一行有兩個正整數 n,m,表示網格圖的大小, 接下來 n 行,每行 m 個字元,表示這張網格圖。 其中字元“.”表示空地,“#”表示障礙物,“S”表示機器人所在位置。
輸出描述:
一共 T 行,每行一個整數,表示答案。
輸入
3 5 5 ##### #...# .#S#. #...# ##### 1 7 S...... 5 8 #.###### #.#..S.# #.#.##.# #......# ########
輸出
-1 6 -1
備註:
資料範圍 0≤T,n,m≤50
題解
這道題其實就是在周圍都沒有障礙物的情況下,找出所有子序列都不會越界的最大長度。
子串和子序列的區別:
子串必須是挨著的,比如:‘abc’的子串有,‘a’,‘b’,‘c’,‘ab’,‘bc’,‘abc’
而子序列可以是分開的,比如:‘abc’的子序列有,‘a’,‘b’,‘c’,‘ab’,‘ac’,‘bc’,‘abc’
咳咳,言歸正傳,如果起點四個方向上有障礙物(“#”)的話,就存在長度為正無窮的長度,輸出 -1 即可。
問題就在於如果不為正無窮,長度應為多少?
題上說, RUR 指令,到機器人那裡就可能變成 RR 或者變成 U,所以要使任何子序列都是安全的,從任意一位開始,怎樣擷取,都不可以超過邊界。畫個圖表示一下
。。。有點醜湊乎看吧,先假設都可以走,總結一下規律
4 * 7 的矩陣,要使機器人怎麼都不會掉下去,也就是怎麼組合都不會越界,那麼,向右走的距離不能大於5,向左不能大於1,向上不能大於2,向下不能大於1。組合一下,就是橫向走不能大於6(7個點走6步),縱向不能大於3(4個點走3步)。
所以,最長距離就是 n+m-2
# include <cstdio>
# include <cmath>
# include <cstring>
# include <algorithm>
using namespace std;
const int maxn = 55;
char s[maxn][maxn];
int mark;
int n, m;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int sx, sy;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf(" %c",&s[i][j]);
if(s[i][j] == 'S')
{
sx = i;
sy = j;
}
}
mark = 0;
for(int i=1;i<=n;i++)
if(s[i][sy] == '#')
mark = 1;
for(int i=1;i<=m;i++)
if(s[sx][i] == '#')
mark = 1;
if(mark) printf("-1\n");
else printf("%d\n",n+m-2);
}
return 0;
}