【洛谷p1902】刺杀大佬(雾)
最开始我想这个题,第一眼是棋盘dp,结果超时了,而后打了个dfs,超时超的比dp还狠,最后打了个二分+bfs,终于a了
结论:这个题真恶心,看来心里没点b树(雾)
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; struct in { int x,y; }; queue<in>qwq; int fx[5]={0,-1,0,1,0},fy[5]={0,0,1,0,-1}; int n,m,l,mid,r,ans,mx=-1000000007,mi=1000000007,mmp[1010][1010],dp[1010][1010]; bool flag[1010][1010]; bool bfs() { memset(flag,0,sizeof(flag)); while(!qwq.empty()) qwq.pop(); for(int i=1;i<=m;i++) if(mmp[2][i]<=mid) qwq.push((in){2,i}),flag[2][i]=1;//初始化 while(!qwq.empty()) { in qaq=qwq.front(); if(qaq.x==n)//如果能走到最后一行,因为最后一行杀伤力为0,所以自然对答案没有影响 return 1; for(int i=1;i<=4;i++) { if(qaq.x+fx[i]<=1||qaq.y+fy[i]<1||qaq.y+fy[i]>m)//防止数组越界 continue; if(mmp[qaq.x+fx[i]][qaq.y+fy[i]]<=mid&&!flag[qaq.x+fx[i]][qaq.y+fy[i]])//如果没走过而且这个点比答案小 qwq.push((in){qaq.x+fx[i],qaq.y+fy[i]}),flag[qaq.x+fx[i]][qaq.y+fy[i]]=1;//加入队列 } qwq.pop(); } return 0; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&mmp[i][j]); for(int i=2;i<=n-1;i++) for(int j=1;j<=m;j++) mx=max(mx,mmp[i][j]),mi=min(mi,mmp[i][j]);//预处理下最大最小值,便于下面二分 l=mi,r=mx; while(l<r) { mid=l+r>>1; if(bfs())//返回真则说明答案偏大,可以去掉一些较大的点 r=mid; else//否则说明答案太小 l=mid+1; } printf("%d",l); }