This question faces a little difficult to understand, it is recommended to jump directly to that part of the explanation of the meaning of problems (although I think the explanation is not right, but in accordance with the explanation really do AC);
According to "explain the meaning of the questions," the idea to think about this question, then it is very simple:
1. First To read this character matrix, you can use cin (TLE will not know), here I use getchar reads;
2. From the '*' wide search began again, recording what each '#' is searched to time, until all the points have been traversed;
3. Find all the '#' position of the maximum time, the first question is the answer, for the time being recorded as much;
4. Because through the lattice per unit time is increased by one point height, so for a particular grid i, if it traverse the shortest time t i , then its contribution answer is: much - t i + 1, will the contribution of each grid add up is the answer to the second question it;
5. Consider the case where no solution is determined: O (nm) scan through all the lattice violent, if the time to traverse the case (a grid that is not traversed), 0 indicating no occurrence of solution;
code show as below:
#include<iostream> #include<cstdio> #include<queue> #include<cmath> using namespace std; const int mod=19260817; char read() //自定义字符读入 { char ch=getchar(); while(ch!='*'&&ch!='o'&&ch!='#') ch=getchar(); //不是题目中的三种字符就一直往下读 return ch; } struct juanzi //开一个结构体,存每一个格子的信息:最先被遍历的时间是t,坐标是(x1,y1) { int t,x1,y1; }b[250001]; queue<juanzi> q; //开一个结构体类型的队列 char a[501][501]; //存输入的字符矩阵 int n,m,start,endd,xx,yy; //n*m的矩阵,打印机'*'的坐标是(start,endd),注意不要用end,好像会和STL里面的东西重名(我CE我知道) int dx[5]={0,1,0,-1,0}; //四个方向 int dy[5]={0,0,-1,0,1}; int vis[501][501]; //存每个点被遍历的时间 int ans,much; void bfs() { q.push((juanzi){0,start,endd}); //起点入队 juanzi f; while(!q.empty()) //其实我们每一步都判断是否将所有点都遍历过,只需判队列非空就好啦,队列为空就说明无法再遍历到其他的点了 { f=q.front(); q.pop(); for(int i=1;i<=4;i++) { xx=f.x1+dx[i]; //往四个方向走 yy=f.y1+dy[i]; if(a[xx][yy]=='#'&&vis[xx][yy]==0) //如果可以走并且之前没走过,那就走 { vis[xx][yy]=f.t+1; //到这个格子的时间是上一个格子的时间再加一 q.push((juanzi){f.t+1,xx,yy}); //入队去遍历下面的格子 } } } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { a[i][j]=read(); if(a[i][j]=='*') //记录下打印机'*'的位置 { start=i; endd=j; vis[i][j]=-1; //把不能遍历的点的时间全赋成-1 } if(a[i][j]=='o') vis[i][j]=-1; //花盆的位置 } bfs(); //核心代码:广度优先搜索 for(int i=1;i<=n;i++) //判无解的情况 for(int j=1;j<=m;j++) if(vis[i][j]==0) { cout<<-1;return 0; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) much=max(much,vis[i][j]); //找最后被遍历到的点所需要的时间 printf("%d\n",much); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(vis[i][j]>0) //排除了打印机'*'和花盆'o'的位置 { ans=(ans+(much-vis[i][j]+1)%mod)%mod; //每个格子的贡献 } } printf("%d",ans); return 0; } /* 其实由于数据有锅,无解的情况没有看出来,当成有解的情况做了; AC代码要注释掉那个判断无解的情况QwQ~ 但加上那一段判无解的代码应该才是最正确的 */