2 solutions

  • 2
    @ 2025-2-18 20:50:39
    #include <bits/stdc++.h>
    //不要点差评!!!!
    using namespace std;
    char k[1001][1001];
    //第三维表示是否使用过魔法液,0表示没用过,1表示使用过了
    bool vis[1001][1001][2];
    //新增:一开始使用一个二维数组zis[x][y]标记是否使用魔法液,但是不能做到实时变化,所以考虑增加第三维
    int h, w, d, r, fs;
    //bool zis[1001][1001];
    struct node {
    	//x,y为下标,s记录是否重复,cnt记录次数
    	int x, y, s, cnt;
    };
    
    const int dx[8] = {0, 0, 1, -1, -1, 1, -1, 1};
    const int dy[8] = {1, -1, 0, 0, -1, 1, 1, -1};
    int bfs(int a, int b) {
    	queue<node> q;
    	//初始没有重复,次数为0
    	q.push({a, b, 0, 0});
    	vis[a][b][0] = 1;
    	while (!q.empty()) {
    		node ds = q.front();
    		q.pop();
    		int cx = ds.x;
    		int cy = ds.y;
    		//找到时返回
    		if (cx == h && cy == w) {
    			return ds.cnt;
    		}
    		fs = ds.s;//取出来方便使用
    		for (int i = 0; i < 4; i++) {
    			int nx = cx + dx[i];
    			int ny = cy + dy[i];
    			//判断是否越界,障碍物,!走重复路!
    			if (nx >= 1 && ny >= 1 && nx <= h && ny <= w && vis[nx][ny][fs]==0 && k[nx][ny] != '#') {
    				//标记为走过
    				vis[nx][ny][fs] = 1;
            //重复判断(fs)沿用以前,次数+1
    				q.push({nx, ny, fs, ds.cnt + 1});
    			}
    		}
    		int nx = cx + d;
    		int ny = cy + r;
    		//判断是否可以使用魔法液
    		//!vis[nx][ny][1] 表示当前格子没使用过,fs==0表示以前没使用过
        //if(zis[nx][ny]==1)表示此位置用魔法液到达过
    		if (nx >= 1 && ny >= 1 && nx <= h && ny <= w  && k[nx][ny] == '.' && fs == 0 && !vis[nx][ny][1]) {
    			//标记该格子使用过魔法液
    			vis[nx][ny][1] = 1;
          //zis[nx][ny]=1;坏处只能判断一次
    			//以后也不能用了(只能用一次)fs标记为1
    			q.push({nx, ny, 1, ds.cnt + 1});
    		}
    
    	}
    	return -1;
    }
    int main() {
    	cin >> h >> w >> d >> r;
    	for (int i = 1; i <= h; i++) {
    		for (int j = 1; j <= w; j++) {
    			cin >> k[i][j];
    		}
    	}
    	cout << bfs(1, 1);
    	return 0;
    }
    
    • @ 2025-2-19 20:09:02

      讨伐无脑差评😡 不过建议题解分析一下debug找思路的过程,分析为什么有第三维,处理什么特征数据,提高技术含量

  • 1
    @ 2025-2-19 13:41:45
    #include<iostream>
    #include<queue> 
    #define N 1001
    
    using namespace std;
    
    struct node{
    	int x,y,step;	//x,y为坐标,step记录操作数 
    	bool drunk;		//嗑没嗑药 
    };
    
    queue<node> q;		//BFS经典队列 
    const int dx[]={-1,0,1,0},dy[]={0,-1,0,1};	//四个方向的偏移量 
    char mp[N][N]={};	//地图 
    bool vis[N][N][2]={};	//第 3 维判断嗑没嗑药
    int h,w,d,r;
    
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(NULL);
    	cout.tie(NULL);
    	
    	cin>>h>>w>>d>>r;
    	
    	for(int i=1;i<=h;++i)
    		for(int j=1;j<=w;++j)
    			cin>>mp[i][j];
    			
    	vis[1][1][0]=true;	//初始化,第一次没嗑药 
    	q.push((node){1,1,0,false});	// 初始化,第一次没嗑药,step为 0 
    	
    	while(!q.empty())
    	{
    		node f=q.front();	//取出队首 
    		q.pop();	//丢弃队首 
    		
    		for(int i=0;i<4;++i)
    		{
    			int px=f.x+dx[i],py=f.y+dy[i];	//计算偏移 
    			
    			if(px>0 && px<=h && py>0 && py<=w && !vis[px][py][f.drunk] && mp[px][py]!='#')	 
    			{
    				if(px==h && py==w)	//找到时,输出答案,退出程序 
    				{
    					cout<<f.step+1;
    					return 0;
    				}
    				
    				vis[px][py][f.drunk]=true;	//标记 
    				q.push((node){px,py,f.step+1,f.drunk});	//合法情况入队 
    			}
    		}
    		
    		if(!f.drunk)//if没嗑药 
    		{
    			int px=f.x+d,py=f.y+r;	//计算偏移 
    			
    			if(px>0 && px<=h && py>0 && py<=w && !vis[px][py][1] && mp[px][py]!='#')	//判断越界 && 重复 && 障碍
    			{
    				if(px==h && py==w)	//找到时,输出答案,退出程序 
    				{
    					cout<<f.step+1;
    					return 0;
    				}
    				
    				vis[px][py][1]=true;	//标记该格子使用了药水 
    				q.push((node){px,py,f.step+1,true});//喝过了,drunk 标记为 true 
    			}
    		}
    	}
    	
    	cout<<-1;//运行到这说明逃不出去 
    	return 0;//退出程序
    }
    
    • @ 2025-2-19 20:09:24

      建议题解分析一下debug找思路的过程,分析为什么有第三维,处理什么特征数据,提高技术含量

  • 1

Information

ID
994
Time
1000ms
Memory
125MiB
Difficulty
9
Tags
# Submissions
53
Accepted
6
Uploaded By