題目網址:https://www.luogu.com.cn/problem/P1363ios
迷宮是無限多塊地圖拼接而成的,問是否能夠在迷宮中走無限遠。解決方案是dfs,走出初始地圖以後的位置映射到原位置(取模),若是同一個映射位置兩次通過的座標不同,則表示這個位置能夠無限屢次通過,就走不出迷宮。c++
代碼以下:ui
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define scand(x) scanf("%llf",&x) 11 #define f(i,a,b) for(int i=a;i<=b;i++) 12 #define scan(a) scanf("%d",&a) 13 #define dbg(args) cout<<#args<<":"<<args<<endl; 14 #define pb(i) push_back(i) 15 #define ppb(x) pop_back(x) 16 #define inf 0x3f3f3f3f 17 #define maxn 1505 18 int n,m,t,sx,sy; 19 bool flag=false; 20 char Map[maxn][maxn]; 21 int vis[maxn][maxn][3];//第一維存放是否訪問過,第2、三維存放第一次 訪問的橫縱座標 22 int dir[][2]={{0,1},{0,-1},{-1,0},{1,0}}; 23 void dfs(int mx,int my,int x,int y,int dep) 24 { 25 if(flag)return; 26 // pf("%d:%d %d\n",dep,x,y); 27 if(vis[mx][my][0]&&(vis[mx][my][1]!=x||vis[mx][my][2]!=y))//從(x,y)位置會到達像(x,y+/-m)這樣的位置,因此只有一個座標不一樣 28 {//代表映射座標是第二次到達,能夠到達兩次則能夠到達無窮次 29 flag=true; 30 return; 31 } 32 //若是已經標誌第一次通過該點搜索失敗,則下一次從這個點開始深搜一樣會失敗,跳過 33 if(vis[mx][my][0]&&vis[mx][my][1]==x&&vis[mx][my][2]==y)return; 34 35 vis[mx][my][0]=1;//第一次訪問,設置第一次訪問的座標信息 36 vis[mx][my][1]=x; 37 vis[mx][my][2]=y; 38 int xx,yy,modx,mody; 39 f(i,0,3) 40 { 41 xx=x+dir[i][0]; 42 yy=y+dir[i][1]; 43 44 modx=(xx+(n*2))%n;//正向取模,防止模數非正 45 mody=(yy+(m*2))%m; 46 if(Map[modx][mody]) 47 { 48 dfs(modx,mody,xx,yy,++dep); 49 } 50 } 51 } 52 char c; 53 int main() 54 { 55 //freopen("input.txt","r",stdin); 56 //freopen("output.txt","w",stdout); 57 std::ios::sync_with_stdio(false); 58 while(scanf("%d%d",&n,&m)!=EOF) 59 { 60 mem(Map,0); 61 f(i,0,n-1) 62 { 63 f(j,0,m-1) 64 { 65 scanf(" %c",&c); 66 if(c=='.')Map[i][j]=1; 67 if(c=='S') 68 { 69 Map[i][j]=1; 70 sx=i; 71 sy=j; 72 } 73 } 74 75 } 76 flag=false; 77 mem(vis,0); 78 dfs(sx,sy,sx,sy,0); 79 if(flag)pf("Yes\n"); 80 else pf("No\n"); 81 } 82 83 }