CF173B Chamber of Secrets ###K //K
题目链接:https://www.luogu.com.cn/problem/CF173B
题意:从1 1 射进一道向右的光线 每次遇到 # 的时候可以选择向四个方向发散一次, 或者沿原来的方向继续,
问能否最后到达n m的时候且 方向向右射出 求出最少的 #的发散次数
思路:因为题目满足01 bfs 的条件 所以直接考虑01bfs 对光线是否发散来处理
要注意的是 当到达n m 方向不为右 但是该格子是 # 的时候要特判
且vis要记录方向 来避免重复走
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define pb push_back 5 const int mod=1e4; 6 const int maxn=1e3+10; 7 char s[maxn][maxn]; 8 int vis[maxn][maxn][5]; 9 int xx[5]={58,0,0,1,-1}; 10 int yy[5]={58,1,-1,0,0}; 11 //r l d u 12 13 14 struct ac 15 { 16 int x,y,step; 17 int f; 18 }; 19 20 21 int main() 22 { 23 ios::sync_with_stdio(0); 24 cin.tie(0); 25 int n,m; 26 cin>>n>>m; 27 for(int i=1;i<=n;i++) 28 { 29 for(int j=1;j<=m;j++) 30 { 31 cin>>s[i][j]; 32 } 33 } 34 int ans=-1; 35 deque<ac>q; 36 q.push_back({1,1,0,1}); 37 vis[1][1][1]=1; 38 while(!q.empty()) 39 { 40 ac u=q.front(); 41 q.pop_front(); 42 int x=u.x,y=u.y; 43 //cout<<x<<" "<<y<<" "<<u.f<<'\n'; 44 if(x==n&&u.f==1) 45 { 46 cout<<x<<" "<<y<<'\n'; 47 ans=u.step; 48 break; 49 } 50 if(x==n&&y==m&&s[x][y]=='#') 51 { 52 ans=u.step+1; 53 break; 54 } 55 int tx=x+xx[u.f],ty=y+yy[u.f]; 56 if(tx<1||ty<1||tx>n||ty>m||vis[tx][ty][u.f]) 57 { 58 59 } 60 else 61 { 62 vis[tx][ty][u.f]=1; 63 q.push_front({tx,ty,u.step,u.f}); 64 } 65 if(s[x][y]=='#') 66 { 67 for(int i=1;i<=4;i++) 68 { 69 int tx=xx[i]+x; 70 int ty=yy[i]+y; 71 if(tx<1||ty<1||tx>n||ty>m||vis[tx][ty][i]) 72 continue; 73 vis[tx][ty][i]=1; 74 q.push_back({tx,ty,u.step+1,i}); 75 } 76 } 77 } 78 cout<<ans<<'\n'; 79 80 81 } 82 /* 83 5 5 84 .##.. 85 .##.. 86 .#.#. 87 ..#.. 88 ..#.. 89 */
或者直接考虑 起点为 n m+1 终点为1 0 直接写也行 特判边界
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e3+10; 4 const int mod=998244353; 5 #define ll long long 6 #define pb push_back 7 #define pi pair<int,int> 8 #define fi first 9 #define sc second 10 int n,m; 11 char s[maxn][maxn]; 12 int xx[4]={-1,1,0,0}; 13 int yy[4]={0,0,-1,1}; 14 15 struct ac 16 { 17 int x,y,step,d; 18 }; 19 int vis[maxn][maxn][4][2]; 20 int solve() 21 { 22 vis[n][m+1][2][0]=1; 23 deque<ac>q; 24 q.push_back({n,m+1,0,2}); 25 while(!q.empty()) 26 { 27 ac u=q.front(); 28 q.pop_front(); 29 int x=u.x,y=u.y,step=u.step,d=u.d; 30 if(x==1&&y==0) return step; 31 if(s[x][y]=='#') 32 { 33 for(int i=0;i<4;i++) 34 { 35 int tx=x+xx[i],ty=y+yy[i]; 36 if(tx==1&&ty==0) 37 { 38 q.push_back({tx,ty,step+1,i}); 39 vis[tx][ty][i][1]=1; 40 } 41 if(tx<1||tx>n||ty<1||ty>m||vis[tx][ty][i][1]) 42 continue; 43 q.push_back({tx,ty,step+1,i}); 44 vis[tx][ty][i][1]=1; 45 } 46 } 47 int tx=x+xx[d],ty=y+yy[d]; 48 if(tx==1&&ty==0) return step; 49 if(tx<1||tx>n||ty<1||ty>m||vis[tx][ty][d][0]) 50 continue; 51 vis[tx][ty][d][0]=vis[tx][ty][d][1]=1; 52 q.push_front({tx,ty,step,d}); 53 } 54 return -1; 55 } 56 57 58 int main() 59 { 60 ios::sync_with_stdio(0); 61 cin.tie(0); 62 cin>>n>>m; 63 for(int i=1;i<=n;i++) cin>>(s[i]+1); 64 cout<<solve()<<'\n'; 65 66 67 68 69 70 71 }
                    
                
                
            
        
浙公网安备 33010602011771号