济南学习 Day 3 T2 pm

LYK 快跑!(run)
Time Limit:5000ms Memory Limit:64MB
题目描述
LYK 陷进了一个迷宫! 这个迷宫是网格图形状的。 LYK 一开始在(1,1)位置, 出口在(n,m)。
而且这个迷宫里有很多怪兽,若第 a 行第 b 列有一个怪兽,且此时 LYK 处于第 c 行 d 列,此
时这个怪兽对它的威胁程度为|a-c|+|b-d|。
LYK 想找到一条路径,使得它能从(1,1)到达(n,m),且在途中对它威胁程度最小的怪兽的
威胁程度尽可能大。
当然若起点或者终点处有怪兽时,无论路径长什么样,威胁程度最小的怪兽始终=0。
输入格式(run.in)
第一行两个数 n,m。
接下来 n 行,每行 m 个数,如果该数为 0,则表示该位置没有怪兽,否则存在怪兽。
数据保证至少存在一个怪兽。
输入格式(run.out)
一个数表示答案。
输入样例
3 4
0 1 1 0
0 0 0 0
1 1 1 0
输出样例
1
数据范围
对于 20%的数据 n=1。
对于 40%的数据 n<=2。
对于 60%的数据 n,m<=10。
对于 80%的数据 n,m<=100。
对于 90%的数据 n,m<=1000。
对于另外 10%的数据 n,m<=1000 且怪兽数量<=100。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #define N 1010
 6 using namespace std;
 7 int a[N][N],b[N][N],n,m,num,qx[N*N],qy[N*N],vis[N][N];
 8 int ax[4]={0,0,1,-1};
 9 int ay[4]={1,-1,0,0};
10 bool check(int limit)
11 {
12     memset(vis,0,sizeof(vis));
13     memset(qx,0,sizeof(qx));
14     memset(qy,0,sizeof(qy));
15     int head=0,tail=1;
16     qx[1]=1;qy[1]=1;vis[1][1]=1;
17     while(head<tail)
18     {
19         ++head;int nx=qx[head],ny=qy[head];
20         for(int i=0;i<4;i++)
21         {
22             int xx=nx+ax[i],yy=ny+ay[i];
23             if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]&&!a[xx][yy]&&b[xx][yy]>=limit)
24             {
25                 ++tail;qx[tail]=xx;qy[tail]=yy;vis[xx][yy]=1;
26                 if(xx==n&&yy==m)return true;
27             }
28         }
29     }// 宽搜检查是否从起点到终点能行得通 
30     return false;
31 }
32 void BFS()
33 {
34     int head=0,tail=num;
35     while(head<=tail)
36     {
37         ++head;int nx=qx[head],ny=qy[head];
38         for(int i=0;i<4;i++)
39         {
40             int xx=nx+ax[i],yy=ny+ay[i];
41             if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!b[xx][yy]&&!a[xx][yy])
42             {
43                 b[xx][yy]=b[nx][ny]+1;
44                 ++tail;qx[tail]=xx;qy[tail]=yy;
45             }
46         }
47     }
48 }
49 int main()
50 {
51     scanf("%d%d",&n,&m);
52     for(int i=1;i<=n;i++)
53       for(int j=1;j<=m;j++)
54       {
55           scanf("%d",&a[i][j]);
56           if(a[i][j])
57           {
58               qx[++num]=i;qy[num]=j;
59           }
60       }
61     if(a[1][1]||a[n][m])// 特判 
62     {
63         printf("0");
64         return 0;
65     }
66     BFS();
67     int l=0,r=N*N,ans=0;
68     while(l<=r)
69     {
70         int mid=(l+r)/2;//  二分怪兽的影响范围 
71         if(check(mid))
72         {
73             l=mid+1;
74             ans=mid;
75         }
76         else r=mid-1;
77     }
78     printf("%d",ans);
79     return 0;
80 }

思路:见↑↑↑↑↑↑↑↑

最小值中求最大,最大值中求最小,非常符合二分答案的特点(标志)

原文地址:https://www.cnblogs.com/suishiguang/p/6038982.html