题目链接:https://ac.nowcoder.com/acm/problem/21722
题目大意:每个点都有特定的魔物,每个魔物有特定的攻击力,然后史莱姆要从起点到终点救静,当他的攻击力小于等于魔物的攻击力的时候他才能经过,求能够使史莱姆到达终点的他的初始攻击力最小是多少。
题解:这个就是用二分答案结合bfs来找就可以了。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int mmax,mmin,mid;
int ex,ey,sx,sy;
int n;
int mp[505][505];
int vis[505][505];
const int a[4][2]={
1,0,
0,1,
-1,0,
0,-1
};
struct node
{
int x;
int y;
node(int a=0,int b=0):x(a),y(b){};
};
bool bfs()
{
memset(vis,false,sizeof(vis));
queue<node>q;
q.push(node(sx,sy));
vis[q.front().x][q.front().y]=1;
while(!q.empty())
{
for(int i=0;i<4;i++)
{
int tempx=q.front().x+a[i][0];
int tempy=q.front().y+a[i][1];
if(vis[tempx][tempy]==1||tempx<=0||tempx>n||tempy<=0||tempy>n||mp[tempx][tempy]>mid)
continue;
if(tempx==ex&&tempy==ey)
return 1;
q.push(node(tempx,tempy));
vis[tempx][tempy]=1;
}
q.pop();
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
mmax=0;
mmin=100000;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&mp[i][j]);
if(mmax<mp[i][j])
mmax=mp[i][j];
if(mmin>mp[i][j])
mmin=mp[i][j];
}
}
scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
while(mmax-mmin>=1)//最小化最大值
{
mid=(mmax+mmin)/2;
if(bfs())//当前的最大值可以走到终点,但是不一定是最优的,所以向左取
mmax=mid;
else//往右取
mmin=mid+1;
}
printf("%d\n",mmin);
}
return 0;
}