CF97D Robot in Basement
阿新 • • 發佈:2020-11-30
CF97D Robot in Basement
題意翻譯
在一個n*m(n,m <= 150) 的網格上,有一些格子是障礙的,並且網格邊界上的格子均是障礙的,另有一個非障礙的格子是出口。一個機器人可以根據程式在該網格上行走。一段程式是一個由UDLR四種指令組成的字串,機器人會依次執行每個命令,一個指令會使機器人向指定的方向移動一格,如果對應的格子為障礙則不動,現在給定一格長度為l(l <= 1e5)的程式,求它的一個最短字首p,使得對於一開始的網格上任意非障礙位置都是機器人,在執行完程式p之後都停在出口上。
題解:
暴力的思路是一個一個按序列模擬。但是很容易發現的性質是各個機器人的行動是互相獨立的,不存在誰擋誰路的情況。這樣的話,可以在每個空位都放一個機器人,然後大家同步走,直到大家都重合了並且都到終點了,這時就是最少的步數了。
這也就變成了模擬題。
那麼很自然地想到了用0/1表示有沒有機器人,然後用位運算模擬就行。
模擬的時候大約遵從以下思路:因為bitset沒有二維的,所以先考慮把它對映到一維。然後發現機器人一直在左右上下地動,牆是不動的,比較難維護,所以考慮開3個bitset分別記錄牆、機器人、出口。最後,上下左右的模擬需要在一維狀態下進行,這裡需要特殊注意。
程式碼:
#include<cstdio> #include<bitset> using namespace std; const int maxn=155; const int maxm=1e5+5; int n,m,k; int id[maxn][maxn]; char s[maxm]; bitset<50005> a,b,e,mp; void init() { int tot=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) id[i][j]=tot++; } int main() { scanf("%d%d%d",&n,&m,&k); init(); for(int i=1;i<=n;i++) { scanf("%s",s+1); for(int j=1;j<=m;j++) { if(s[j]=='#') mp[id[i][j]]=1; else a[id[i][j]]=1; if(s[j]=='E') e[id[i][j]]=1; } } scanf("%s",s+1); b=a; for(int i=1;i<=k+1;i++) { if(a==e) { printf("%d\n",i-1); return 0; } if(s[i]=='U') a=(((a>>m)&b)|((mp<<m)&a)); else if(s[i]=='D') a=(((a<<m)&b)|((mp>>m)&a)); else if(s[i]=='L') a=(((a>>1)&b)|((mp<<1)&a)); else a=(((a<<1)&b)|((mp>>1)&a)); } puts("-1"); return 0; }