这题背景真的是…这是要引起世界大战呀…
题目意思其实很简单,就是在穿过中间n-2层时最大受到的伤害最小是多少…
这不是很明显的二分吗。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<algorithm>
#define For(i,f,l) int pd=(f<l)*1+(l<=f)*-1;for(i=f;i!=l+pd;i+=pd)
using namespace std;
long long read()//快读
{
long long x=0;int w=1; char ch=0;
while(!isdigit(ch)){if(ch=='-')w=-1;if(ch=='+')w=1;ch=getchar();}
while(isdigit(ch))x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return w*x;
}
void write(long long x)//快输
{
if(x<0){putchar('-');x=-x;}
if(x>9)write(x/10);
putchar(x%10+'0');
}
const int zx[5]={233,0,0,1,-1};//发向的常量数组
const int zy[5]={233,1,-1,0,0};
int i,j,k,m,n,high[1001][1001],fx,fy,L,R,mid,sum,x[1000001],y[1000001],ans;
bool boo[1001][1001];
void first()//把bfs的判重的数组全部赋值为true
{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
boo[i][j]=true;
}
bool check(int mid)//二分的判断
{
int i,j,k,h,t,num=sum;
x[1]=1;
y[1]=1;
first();
boo[fx][fy]=0;
h=1;
t=1;
//bfs的初始化
while(t<=h)
{
if(x[t]==n)return 1;//可以走过去
for(i=1;i<=4;i++)
if(high[x[t]+zx[i]][y[t]+zy[i]]<=mid&&boo[x[t]+zx[i]][y[t]+zy[i]])//判断下一个是否可以走
{
h++;
x[h]=x[t]+zx[i];
y[h]=y[t]+zy[i];
boo[x[h]][y[h]]=false;
}
t++;
}
return 0;//不可以则返回false
}
int main()
{
n=read();
m=read();
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
high[i][j]=read(),R=max(R,high[i][j]);//找到最大伤害为二分的上限
L=0;
while(R>=L)//标准的二分
{
mid=(R+L)/2;
if(check(mid)){R=mid-1;ans=mid;/*记录答案*/}else L=mid+1;
}
write(ans);//输出答案QAQ
return 0;
}
这个可以说是二分和bfs的模板题了…
给道类似的题目再练练吧