2 条题解

  • 1
    @ 2023-12-17 15:47:18

    从小明家和小明位置分别用bfs遍历到每个点的最短距离,然后再遍历所有的钥匙的点,最后我们从钥匙中找到到小明家和小明位置距离之和的最小值即可

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2010, INF = 0x3f3f3f3f;
    int n, m;
    int vis[N][N];
    int ret[2][N][N];
    char a[N][N];
    int xx[4] = {1,-1,0,0};
    int yy[4] = {0,0,1,-1};
    void bfs(int xxx, int yyy, int d){
    	queue<pair<int,int> > q;
    	q.push(make_pair(xxx,yyy));
    	vis[xxx][yyy] = 1;
    	ret[d][xxx][yyy] = 0;
    	while(!q.empty()){
    		int tx = q.front().first;
    		int ty = q.front().second;
    		q.pop();
    		for (int i = 0; i < 4; i ++){
    			int x = tx + xx[i];
    			int y = ty + yy[i];
    			if(x >= 0 && x < n && y >= 0 && y < m && a[x][y] != '#' && !vis[x][y]){
    				ret[d][x][y] = ret[d][tx][ty] + 1;
    				vis[x][y] = 1;
    				q.push(make_pair(x,y));
    			}
    		}
    	}
    	
    }
    int main(){
    	queue<pair<int, int> > q;
    	cin >> n >> m;
    	memset(ret,INF, sizeof ret);
    	memset(vis,0, sizeof vis);
    	int sx, sy;
    	int tx, ty;
    	for (int i = 0; i < n; i ++){
    		cin >> a[i];
    		for (int j = 0; j < m; j ++){
    			if(a[i][j] == 'P'){
    				q.push(make_pair(i,j));
    			}else if(a[i][j] == 'S'){
    				sx = i;
    				sy = j;
    			}else if(a[i][j] == 'T'){
    				tx = i;
    				ty = j;
    			}
    			
    		}
    	}
    	bfs(sx, sy, 0);
    	memset(vis, 0, sizeof vis);
    	bfs(tx,ty, 1);
    	int ans = INF;
    	while(!q.empty()){
    		int x = q.front().first;
    		int y = q.front().second;
    		q.pop();
    		ans = min(ans, ret[0][x][y]+ret[1][x][y]);
    	}
    	cout << ans;
    	return 0;
    }
    
    • -1
      @ 2023-12-17 15:46:02

      设置当前状态是否有拿过钥匙

      #include<bits/stdc++.h>
      using namespace std;
      const int N = 2010;
      typedef pair<int,int> pii;
      typedef pair<pii,int> piii;
      int dx[4] = {1,0,0,-1},dy[4] = {0,1,-1,0};
      char g[N][N];
      int bx, by, ex, ey;
      int d[N][N];
      int vis[N][N][2];
      int n, m;
      bool in(int x,int y){
          return x > 0 && x <= n && y > 0 && y <= m;
      }
      
      void bfs(){
          queue<pii> q;
          q.push({bx,by});
          vis[bx][by][0] = 1;
          while(!q.empty()){
              pii t = q.front();
              q.pop();
              int x = t.first, y = t.second;
              if(g[x][y] == 'P'){
                  vis[x][y][1] = vis[x][y][0];//将这个继承上去。
              }
              if(g[x][y] == 'T' && vis[x][y][1]){
                  cout << vis[x][y][1] - 1;
                  return;
              }
              for (int i = 0; i < 4; i ++){
                  int tx = x + dx[i], ty = y + dy[i];
                  if(in(tx, ty) && g[tx][ty] != '#'){//如果tx,ty在范围里面
                      if(vis[x][y][1] && !vis[tx][ty][1]){//如果之前的位置是已经拿过钥匙了,而这个位置没拿过钥匙,那我也可以更新。
                          vis[tx][ty][1] = vis[x][y][1] + 1;//步数+1
                          q.push({tx,ty});
                      }
                      if(!vis[tx][ty][0]){
                          vis[tx][ty][0] = vis[x][y][0] + 1;
                          q.push({tx,ty});
                      }
                  }
              }
          }
      }
      int main(){
          freopen("home.in","r",stdin);
          freopen("home.out","w",stdout);
          cin >> n >> m;
          for (int i = 1; i <= n; i ++){
              for (int j = 1; j <= m; j ++){
                  cin >> g[i][j];
                  if(g[i][j] == 'S'){
                      bx = i, by = j;
                  }
              }
          }
          bfs();
          return 0;
      }
      
      • 1

      信息

      ID
      559
      时间
      1000ms
      内存
      256MiB
      难度
      8
      标签
      (无)
      递交数
      63
      已通过
      12
      上传者