P1902 刺杀大使

这题背景真的是…这是要引起世界大战呀…
题目意思其实很简单,就是在穿过中间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的模板题了…
给道类似的题目再练练吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值