top1编程
← 返回题目
题解

【提高】防御迷阵

1 条题解

  • 0
    @ 2026-7-28 23:26:00
    #include <bits/stdc++.h>
    using namespace std;
    int n, m;
    int a[1005][1005];
    bool f[1005][1005];  // 标记 
    int q[1000005][3];  // 队列 (对应的坐标q[i][1]和q[i][2]存的是i的x,y坐标)
    int fx[5] = {0,-1, 0, 1, 0};
    int fy[5] = {0,0, 1, 0, -1};
    // 判断从xy点出发,在伤害值最大为mid的情况下,是否能走到最后一行 
    bool bfs(int x, int y, int mid){
    	int head=1, tail=1;
    	memset(f,0,sizeof(f));  // 标记所有的点没有走过
    	// 出发点
    	q[1][1] = x;
    	q[1][2] = y;
    	// 队列不为空,即还有房间可以遍历 
    	while(head <= tail){
    		for(int i=1;i<=4;i++){
    			int tx = q[head][1] + fx[i];
    			int ty = q[head][2] + fy[i];
    			// 不满足的点,排除 
    			if(tx == n){
    				return true;  // 到达终点
    			} 
    			if(tx >= 1&&tx <=n &&ty>=1&&ty<=m&&f[tx][ty]==0&&a[tx][ty]<=mid){
    				// 入队 
    				tail++;
    				q[tail][1] = tx;
    				q[tail][2] = ty;
    				f[tx][ty] = 1;  // 标记该点走过 
    			} 
    		}
    		head++;  // 出队 
    	}
    	return false;
    }
    int main(){
    	int l=INT_MAX, r=INT_MIN;
    	cin >> n >> m;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=m;j++){
    			cin >> a[i][j];
    			l = min(l, a[i][j]);  // l记录伤害值最小值 
    			r = max(r, a[i][j]);  // r记录伤害值最大值 
    		}
    	}
    	// 在伤害值的最大和最小之间找 
    	int mid;
    	while(l <= r){
    		mid = l+(r-l)/2;
    		// mid可行,说明mid还能再小 
    		if(bfs(1,1,mid)){
    			r = mid - 1;
    		} else{
    			l = mid + 1;  // mid不可行,说明太小,需要往大的找 
    		}
    	}
    	cout << l;
    	return 0;
    }
    
    • 1